summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2002-04-13 04:58:45 +0000
committerHavoc Pennington <hp@src.gnome.org>2002-04-13 04:58:45 +0000
commitd02060e201de567d26b2eda5d019d19d9b19f807 (patch)
treebdb8f14c692efaa7bb1744c754dd5b483d4c2a3c /src
parentf965726d15950bc4e83409fe73bb2b7588781e81 (diff)
downloadmetacity-d02060e201de567d26b2eda5d019d19d9b19f807.tar.gz
metacity-d02060e201de567d26b2eda5d019d19d9b19f807.tar.bz2
new file containing all the wacky mess I just added to a simple "click the
2002-04-13 Havoc Pennington <hp@pobox.com> * src/delete.c: new file containing all the wacky mess I just added to a simple "click the close button", contains all the dealing-with-dead-application cruft. Use metacity-window-demo to test by clicking the toolbar button that locks it up.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/delete.c492
-rw-r--r--src/display.c2
-rw-r--r--src/metacity-dialog.c67
-rw-r--r--src/window.c141
-rw-r--r--src/window.h12
6 files changed, 600 insertions, 115 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index d78f572..85c9c14 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,6 +7,7 @@ metacity_SOURCES= \
common.h \
core.c \
core.h \
+ delete.c \
display.c \
display.h \
effects.c \
diff --git a/src/delete.c b/src/delete.c
new file mode 100644
index 0000000..c7416c4
--- /dev/null
+++ b/src/delete.c
@@ -0,0 +1,492 @@
+/* Metacity window deletion */
+
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "util.h"
+#include "window.h"
+#include "errors.h"
+
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+static void meta_window_present_delete_dialog (MetaWindow *window);
+
+static void
+delete_ping_reply_func (MetaDisplay *display,
+ Window xwindow,
+ void *user_data)
+{
+ MetaWindow *window = user_data;
+
+ meta_topic (META_DEBUG_PING,
+ "Got reply to delete ping for %s\n",
+ window->desc);
+
+ /* we do nothing */
+}
+
+static Window
+window_from_string (const char *str)
+{
+ char *end;
+ unsigned long l;
+
+ end = NULL;
+
+ l = strtoul (str, &end, 16);
+
+ if (end == NULL || end == str)
+ {
+ meta_warning (_("Could not parse \"%s\" as an integer"),
+ str);
+ return None;
+ }
+
+ if (*end != '\0')
+ {
+ meta_warning (_("Did not understand trailing characters \"%s\" in string \"%s\""),
+ end, str);
+ return None;
+ }
+
+ return l;
+}
+
+static int
+pid_from_string (const char *str)
+{
+ char *end;
+ long l;
+
+ end = NULL;
+
+ l = strtol (str, &end, 10);
+
+ if (end == NULL || end == str)
+ {
+ meta_warning (_("Could not parse \"%s\" as an integer"),
+ str);
+ return None;
+ }
+
+ if (*end != '\0')
+ {
+ meta_warning (_("Did not understand trailing characters \"%s\" in string \"%s\""),
+ end, str);
+ return None;
+ }
+
+ return l;
+}
+
+static gboolean
+parse_dialog_output (const char *str,
+ int *pid_out,
+ Window *win_out)
+{
+ char **split;
+
+ split = g_strsplit (str, "\n", 2);
+ if (split && split[0] && split[1])
+ {
+ g_strchomp (split[0]);
+ g_strchomp (split[1]);
+
+ *pid_out = pid_from_string (split[0]);
+ *win_out = window_from_string (split[1]);
+
+ g_strfreev (split);
+
+ return TRUE;
+ }
+ else
+ {
+ g_strfreev (split);
+ meta_warning (_("Failed to parse message \"%s\" from dialog process\n"),
+ str);
+ return FALSE;
+ }
+}
+
+static void
+search_and_destroy_window (int pid,
+ Window xwindow)
+{
+ /* Find the window with the given dialog PID,
+ * double check that it matches "xwindow", then
+ * kill the window.
+ */
+ GSList *tmp;
+ gboolean found;
+
+ if (xwindow == None)
+ {
+ meta_topic (META_DEBUG_PING,
+ "Window to destroy is None, doing nothing\n");
+ return;
+ }
+
+ found = FALSE;
+ tmp = meta_displays_list ();
+ while (tmp != NULL)
+ {
+ GSList *windows = meta_display_list_windows (tmp->data);
+ GSList *tmp2;
+
+ tmp2 = windows;
+ while (tmp2 != NULL)
+ {
+ MetaWindow *w = tmp2->data;
+
+ if (w->dialog_pid == pid)
+ {
+ if (w->xwindow != xwindow)
+ meta_topic (META_DEBUG_PING,
+ "Dialog pid matches but not xwindow (0x%lx vs. 0x%lx)\n",
+ w->xwindow, xwindow);
+ else
+ {
+ meta_window_kill (w);
+ found = TRUE;
+ }
+ }
+
+ tmp2 = tmp2->next;
+ }
+
+ g_slist_free (windows);
+
+ tmp = tmp->next;
+ }
+
+ if (!found)
+ meta_topic (META_DEBUG_PING,
+ "Did not find a window with dialog pid %d xwindow 0x%lx\n",
+ pid, xwindow);
+}
+
+static void
+release_window_with_fd (int fd)
+{
+ /* Find the window with the given dialog PID,
+ * double check that it matches "xwindow", then
+ * kill the window.
+ */
+ GSList *tmp;
+ gboolean found;
+
+ found = FALSE;
+
+ tmp = meta_displays_list ();
+ while (tmp != NULL)
+ {
+ GSList *windows = meta_display_list_windows (tmp->data);
+ GSList *tmp2;
+
+ tmp2 = windows;
+ while (tmp2 != NULL)
+ {
+ MetaWindow *w = tmp2->data;
+
+ if (w->dialog_pid >= 0 &&
+ w->dialog_pipe == fd)
+ {
+ meta_topic (META_DEBUG_PING,
+ "Removing dialog with fd %d pid %d from window %s\n",
+ fd, w->dialog_pid, w->desc);
+ meta_window_free_delete_dialog (w);
+ found = TRUE;
+ }
+
+ tmp2 = tmp2->next;
+ }
+
+ g_slist_free (windows);
+
+ tmp = tmp->next;
+ }
+
+ if (!found)
+ meta_topic (META_DEBUG_PING,
+ "Did not find a window with a dialog pipe %d\n",
+ fd);
+}
+
+static gboolean
+io_from_ping_dialog (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer data)
+{
+ meta_topic (META_DEBUG_PING,
+ "IO handler from ping dialog, condition = %x\n",
+ condition);
+
+ if (condition & G_IO_IN)
+ {
+ char *str;
+ int len;
+ GError *err;
+
+ /* Go ahead and block for all data from child */
+ str = NULL;
+ len = 0;
+ err = NULL;
+ g_io_channel_read_to_end (channel,
+ &str, &len,
+ &err);
+
+ if (err)
+ {
+ meta_warning (_("Error reading from dialog display process: %s\n"),
+ err->message);
+ g_error_free (err);
+ }
+
+ meta_topic (META_DEBUG_PING,
+ "Read %d bytes strlen %d \"%s\" from child\n",
+ len, strlen (str), str);
+
+ if (len > 0)
+ {
+ /* We're supposed to kill the given window */
+ int pid;
+ Window xwindow;
+
+ if (parse_dialog_output (str, &pid, &xwindow))
+ search_and_destroy_window (pid, xwindow);
+ }
+
+ g_free (str);
+ }
+
+ release_window_with_fd (g_io_channel_unix_get_fd (channel));
+
+ /* Remove the callback */
+ return FALSE;
+}
+
+static void
+delete_ping_timeout_func (MetaDisplay *display,
+ Window xwindow,
+ void *user_data)
+{
+ MetaWindow *window = user_data;
+ GError *err;
+ int child_pid;
+ int outpipe;
+ char *argv[5];
+ char *window_id_str;
+ GIOChannel *channel;
+
+ meta_topic (META_DEBUG_PING,
+ "Got delete ping timeout for %s\n",
+ window->desc);
+
+ if (window->dialog_pid >= 0)
+ {
+ meta_window_present_delete_dialog (window);
+ return;
+ }
+
+ window_id_str = g_strdup_printf ("0x%lx", window->xwindow);
+
+ argv[0] = METACITY_LIBEXECDIR"/metacity-dialog";
+ argv[1] = "--kill-window-question";
+ argv[2] = window->title;
+ argv[3] = window_id_str;
+ argv[4] = NULL;
+
+ err = NULL;
+ if (!g_spawn_async_with_pipes ("/",
+ argv,
+ NULL,
+ 0,
+ NULL, NULL,
+ &child_pid,
+ NULL,
+ &outpipe,
+ NULL,
+ &err))
+ {
+ meta_warning (_("Error launching metacity-dialog to ask about killing an application: %s\n"),
+ err->message);
+ g_error_free (err);
+ goto out;
+ }
+
+ window->dialog_pid = child_pid;
+ window->dialog_pipe = outpipe;
+
+ channel = g_io_channel_unix_new (window->dialog_pipe);
+ g_io_add_watch_full (channel, G_PRIORITY_DEFAULT,
+ G_IO_IN | G_IO_HUP | G_IO_ERR,
+ io_from_ping_dialog,
+ NULL, NULL);
+ g_io_channel_unref (channel);
+
+ out:
+ g_free (window_id_str);
+}
+
+void
+meta_window_delete (MetaWindow *window,
+ Time timestamp)
+{
+ meta_error_trap_push (window->display);
+ if (window->delete_window)
+ {
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Deleting %s with delete_window request\n",
+ window->desc);
+ meta_window_send_icccm_message (window,
+ window->display->atom_wm_delete_window,
+ timestamp);
+ }
+ else
+ {
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Deleting %s with explicit kill\n",
+ window->desc);
+ XKillClient (window->display->xdisplay, window->xwindow);
+ }
+ meta_error_trap_pop (window->display);
+
+ meta_display_ping_window (window->display,
+ window,
+ timestamp,
+ delete_ping_reply_func,
+ delete_ping_timeout_func,
+ window);
+
+ if (window->has_focus)
+ {
+ /* This is unfortunately going to result in weirdness
+ * if the window doesn't respond to the delete event.
+ * I don't know how to avoid that though.
+ */
+ meta_topic (META_DEBUG_FOCUS,
+ "Focusing top window because focus window %s was deleted/killed\n",
+ window->desc);
+ meta_screen_focus_top_window (window->screen, window);
+ }
+ else
+ {
+ meta_topic (META_DEBUG_FOCUS,
+ "Window %s was deleted/killed but didn't have focus\n",
+ window->desc);
+ }
+}
+
+
+void
+meta_window_kill (MetaWindow *window)
+{
+ char buf[257];
+
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Killing %s brutally\n",
+ window->desc);
+
+ if (window->wm_client_machine != NULL &&
+ window->net_wm_pid > 0)
+ {
+ if (gethostname (buf, sizeof(buf)-1) == 0)
+ {
+ if (strcmp (buf, window->wm_client_machine) == 0)
+ {
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Killing %s with kill()\n",
+ window->desc);
+
+ if (kill (window->net_wm_pid, 9) < 0)
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Failed to signal %s: %s\n",
+ window->desc, strerror (errno));
+ }
+ }
+ else
+ {
+ meta_warning (_("Failed to get hostname: %s\n"),
+ strerror (errno));
+ }
+ }
+
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Disconnecting %s with XKillClient()\n",
+ window->desc);
+ meta_error_trap_push (window->display);
+ XKillClient (window->display->xdisplay, window->xwindow);
+ meta_error_trap_pop (window->display);
+}
+
+void
+meta_window_free_delete_dialog (MetaWindow *window)
+{
+ if (window->dialog_pid >= 0)
+ {
+ kill (window->dialog_pid, 9);
+ close (window->dialog_pipe);
+ window->dialog_pid = -1;
+ window->dialog_pipe = -1;
+ }
+}
+
+static void
+meta_window_present_delete_dialog (MetaWindow *window)
+{
+ meta_topic (META_DEBUG_PING,
+ "Presenting existing ping dialog for %s\n",
+ window->desc);
+
+ if (window->dialog_pid >= 0)
+ {
+ GSList *windows;
+ GSList *tmp;
+
+ /* Activate transient for window that belongs to
+ * metacity-dialog
+ */
+
+ windows = meta_display_list_windows (window->display);
+ tmp = windows;
+ while (tmp != NULL)
+ {
+ MetaWindow *w = tmp->data;
+
+ if (w->xtransient_for == window->xwindow &&
+ w->res_class &&
+ g_strcasecmp (w->res_class, "metacity-dialog") == 0)
+ {
+ meta_window_activate (w,
+ meta_display_get_current_time (w->display));
+ break;
+ }
+
+ tmp = tmp->next;
+ }
+
+ g_slist_free (windows);
+ }
+}
diff --git a/src/display.c b/src/display.c
index 8f167c3..f8400d9 100644
--- a/src/display.c
+++ b/src/display.c
@@ -2409,7 +2409,7 @@ meta_set_syncing (gboolean setting)
}
}
-#define PING_TIMEOUT_DELAY 3000
+#define PING_TIMEOUT_DELAY 2250
static gboolean
meta_display_ping_timeout (gpointer data)
diff --git a/src/metacity-dialog.c b/src/metacity-dialog.c
index 538b845..1e9b2f7 100644
--- a/src/metacity-dialog.c
+++ b/src/metacity-dialog.c
@@ -23,13 +23,60 @@
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <libintl.h>
#define _(x) dgettext (GETTEXT_PACKAGE, x)
#define N_(x) x
+#include <gdk/gdkx.h>
+
+static Window
+window_from_string (const char *str)
+{
+ char *end;
+ unsigned long l;
+
+ end = NULL;
+
+ l = strtoul (str, &end, 16);
+
+ if (end == NULL || end == str)
+ {
+ g_printerr (_("Could not parse \"%s\" as an integer"),
+ str);
+ return None;
+ }
+
+ if (*end != '\0')
+ {
+ g_printerr (_("Did not understand trailing characters \"%s\" in string \"%s\""),
+ end, str);
+ return None;
+ }
+
+ return l;
+}
+
+static void
+on_realize (GtkWidget *dialog,
+ void *data)
+{
+ const char *parent_str = data;
+ Window xwindow;
+
+ xwindow = window_from_string (parent_str);
+
+ gdk_error_trap_push ();
+ XSetTransientForHint (gdk_display, GDK_WINDOW_XID (dialog->window),
+ xwindow);
+ XSync (gdk_display, False);
+ gdk_error_trap_pop ();
+}
+
static int
-kill_window_question (const char *window_name)
+kill_window_question (const char *window_name,
+ const char *parent_str)
{
GtkWidget *dialog;
@@ -37,7 +84,8 @@ kill_window_question (const char *window_name)
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
_("The window \"%s\" is not responding.\n"
- "Force this application to exit?"),
+ "Force this application to exit?\n"
+ "(Any open documents will be lost.)"),
window_name);
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
@@ -46,14 +94,17 @@ kill_window_question (const char *window_name)
_("Kill application"),
GTK_RESPONSE_ACCEPT,
NULL);
-
+
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_REJECT);
- /* return 0 if we should kill the application */
+ g_signal_connect (G_OBJECT (dialog), "realize",
+ G_CALLBACK (on_realize), (char*) parent_str);
+
+ /* return our PID, then window ID that should be killed */
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
- g_print ("Y");
+ g_print ("%d\n%s\n", (int) getpid (), parent_str);
else
- g_print ("N");
+ g_print ("%d\n0x0\n", (int) getpid ());
return 0;
}
@@ -75,13 +126,13 @@ main (int argc, char **argv)
if (strcmp (argv[1], "--kill-window-question") == 0)
{
- if (argc < 3)
+ if (argc < 4)
{
g_printerr ("bad args to metacity-dialog\n");
return 1;
}
- return kill_window_question (argv[2]);
+ return kill_window_question (argv[2], argv[3]);
}
g_printerr ("bad args to metacity-dialog\n");
diff --git a/src/window.c b/src/window.c
index a40af43..dc80b94 100644
--- a/src/window.c
+++ b/src/window.c
@@ -134,7 +134,6 @@ void meta_window_flush_move_resize (MetaWindow *window);
static void meta_window_apply_session_info (MetaWindow *window,
const MetaWindowSessionInfo *info);
-
static const char*
wm_state_to_string (int state)
{
@@ -160,6 +159,8 @@ meta_window_new (MetaDisplay *display, Window xwindow,
GSList *tmp;
MetaWorkspace *space;
gulong existing_wm_state;
+ char *str;
+ unsigned long cardinal;
meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
@@ -265,6 +266,9 @@ meta_window_new (MetaDisplay *display, Window xwindow,
window = g_new (MetaWindow, 1);
+ window->dialog_pid = -1;
+ window->dialog_pipe = -1;
+
window->xwindow = xwindow;
/* this is in window->screen->display, but that's too annoying to
@@ -380,6 +384,9 @@ meta_window_new (MetaDisplay *display, Window xwindow,
window->res_name = NULL;
window->role = NULL;
window->sm_client_id = NULL;
+ window->wm_client_machine = NULL;
+
+ window->net_wm_pid = -1;
window->xtransient_for = None;
window->xgroup_leader = None;
@@ -399,6 +406,32 @@ meta_window_new (MetaDisplay *display, Window xwindow,
window->initial_workspace = 0; /* not used */
meta_display_register_x_window (display, &window->xwindow, window);
+ if (meta_prop_get_latin1_string (window->display, window->xwindow,
+ window->display->atom_wm_client_machine,
+ &str))
+ {
+ window->wm_client_machine = g_strdup (str);
+ meta_XFree (str);
+
+ meta_verbose ("Window has client machine \"%s\"\n",
+ window->wm_client_machine);
+ }
+
+ if (meta_prop_get_cardinal (window->display, window->xwindow,
+ window->display->atom_net_wm_pid,
+ &cardinal))
+ {
+ if (cardinal <= 0)
+ meta_warning (_("Application set a bogus _NET_WM_PID %ld\n"),
+ cardinal);
+ else
+ {
+ window->net_wm_pid = cardinal;
+ meta_verbose ("Window has _NET_WM_PID %d\n",
+ window->net_wm_pid);
+ }
+ }
+
update_size_hints (window);
update_title (window);
update_protocols (window);
@@ -771,6 +804,7 @@ meta_window_free (MetaWindow *window)
meta_window_unqueue_calc_showing (window);
meta_window_unqueue_move_resize (window);
+ meta_window_free_delete_dialog (window);
tmp = window->workspaces;
while (tmp != NULL)
@@ -846,6 +880,7 @@ meta_window_free (MetaWindow *window)
meta_icon_cache_free (&window->icon_cache);
g_free (window->sm_client_id);
+ g_free (window->wm_client_machine);
g_free (window->role);
g_free (window->res_class);
g_free (window->res_name);
@@ -2483,110 +2518,6 @@ meta_window_get_outer_rect (MetaWindow *window,
*rect = window->rect;
}
-static void
-delete_ping_reply_func (MetaDisplay *display,
- Window xwindow,
- void *user_data)
-{
- MetaWindow *window = user_data;
-
- meta_topic (META_DEBUG_PING,
- "Got reply to delete ping for %s\n",
- window->desc);
-
- /* we do nothing */
-}
-
-static void
-delete_ping_timeout_func (MetaDisplay *display,
- Window xwindow,
- void *user_data)
-{
- MetaWindow *window = user_data;
- GError *err;
- int child_pid;
- int outpipe;
- char *argv[4];
-
- meta_topic (META_DEBUG_PING,
- "Got delete ping timeout for %s\n",
- window->desc);
-
-#if 0
- argv[0] = METACITY_LIBEXECDIR"/metacity-dialog";
- argv[1] = "--kill-window-question";
- argv[2] = window->title;
- argv[3] = NULL;
-
- err = NULL;
- if (!g_spawn_async_with_pipes ("/",
- argv,
- NULL,
- 0,
- NULL, NULL,
- &child_pid,
- NULL,
- &outpipe,
- NULL,
- &err))
- {
- meta_warning (_("Error launching metacity-dialog to ask about killing an application: %s\n"),
- err->message);
- g_error_free (err);
- return;
- }
-#endif
-}
-
-void
-meta_window_delete (MetaWindow *window,
- Time timestamp)
-{
- meta_error_trap_push (window->display);
- if (window->delete_window)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Deleting %s with delete_window request\n",
- window->desc);
- meta_window_send_icccm_message (window,
- window->display->atom_wm_delete_window,
- timestamp);
- }
- else
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Deleting %s with explicit kill\n",
- window->desc);
- XKillClient (window->display->xdisplay, window->xwindow);
- }
- meta_error_trap_pop (window->display);
-
- meta_display_ping_window (window->display,
- window,
- timestamp,
- delete_ping_reply_func,
- delete_ping_timeout_func,
- window);
-
- if (window->has_focus)
- {
- /* This is unfortunately going to result in weirdness
- * if the window doesn't respond to the delete event.
- * I don't know how to avoid that though.
- */
- meta_topic (META_DEBUG_FOCUS,
- "Focusing top window because focus window %s was deleted/killed\n",
- window->desc);
- meta_screen_focus_top_window (window->screen, window);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS,
- "Window %s was deleted/killed but didn't have focus\n",
- window->desc);
- }
-}
-
void
meta_window_focus (MetaWindow *window,
Time timestamp)
diff --git a/src/window.h b/src/window.h
index 7a53f99..019a4af 100644
--- a/src/window.h
+++ b/src/window.h
@@ -66,13 +66,16 @@ struct _MetaWindow
MetaWindowType type;
Atom type_atom;
- /* NOTE these four are not in UTF-8, we just treat them as random
+ /* NOTE these five are not in UTF-8, we just treat them as random
* binary data
*/
char *res_class;
char *res_name;
char *role;
char *sm_client_id;
+ char *wm_client_machine;
+
+ int net_wm_pid;
Window xtransient_for;
Window xgroup_leader;
@@ -236,6 +239,10 @@ struct _MetaWindow
/* Managed by stack.c */
MetaStackLayer layer;
MetaStackOp *stack_op;
+
+ /* Current dialog open for this window */
+ int dialog_pid;
+ int dialog_pipe;
};
MetaWindow* meta_window_new (MetaDisplay *display,
@@ -313,6 +320,7 @@ void meta_window_get_outer_rect (MetaWindow *window,
MetaRectangle *rect);
void meta_window_delete (MetaWindow *window,
Time timestamp);
+void meta_window_kill (MetaWindow *window);
void meta_window_focus (MetaWindow *window,
Time timestamp);
void meta_window_raise (MetaWindow *window);
@@ -372,4 +380,6 @@ gboolean meta_window_same_application (MetaWindow *window,
void meta_window_refresh_resize_popup (MetaWindow *window);
+void meta_window_free_delete_dialog (MetaWindow *window);
+
#endif