diff --git a/ChangeLog b/ChangeLog index 47bc2266c..ffb2f6bc4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2001-10-15 Havoc Pennington + + * src/main.c (meta_restart): add a restart feature, for debugging + + * src/tools/metacity-restart.c: little utility program to trigger + the restart + 2001-10-14 Havoc Pennington * src/frames.c (meta_frames_button_press_event): raise/focus diff --git a/configure.in b/configure.in index 613ebf096..14f4f8e23 100644 --- a/configure.in +++ b/configure.in @@ -42,6 +42,7 @@ dnl AM_GNU_GETTEXT ## here we get the flags we'll actually use PKG_CHECK_MODULES(METACITY, gtk+-2.0 >= 1.3.9) +PKG_CHECK_MODULES(METACITY_RESTART, gtk+-2.0 >= 1.3.9) CFLAGS="$METACITY_CFLAGS $CFLAGS" @@ -85,4 +86,5 @@ AC_OUTPUT([ Makefile src/Makefile src/wm-tester/Makefile +src/tools/Makefile ]) diff --git a/src/Makefile.am b/src/Makefile.am index dfa82de1a..08f52805f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ -SUBDIRS=wm-tester +SUBDIRS=wm-tester tools INCLUDES=@METACITY_CFLAGS@ -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" diff --git a/src/display.c b/src/display.c index 482754ff3..c28c4e2a2 100644 --- a/src/display.c +++ b/src/display.c @@ -136,7 +136,8 @@ meta_display_open (const char *name) "WM_ICON_SIZE", "_KWM_WIN_ICON", "_NET_WM_MOVERESIZE", - "_NET_ACTIVE_WINDOW" + "_NET_ACTIVE_WINDOW", + "_METACITY_RESTART_MESSAGE" }; Atom atoms[G_N_ELEMENTS(atom_names)]; @@ -226,6 +227,7 @@ meta_display_open (const char *name) display->atom_kwm_win_icon = atoms[41]; display->atom_net_wm_moveresize = atoms[42]; display->atom_net_active_window = atoms[43]; + display->atom_metacity_restart_message = atoms[44]; /* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK, * created in screen_new @@ -444,7 +446,7 @@ meta_display_close (MetaDisplay *display) g_free (display->name); all_displays = g_slist_remove (all_displays, display); - + g_free (display); if (all_displays == NULL) @@ -921,6 +923,7 @@ event_callback (XEvent *event, if (screen) { + meta_debug_spew ("client for screen\n"); if (event->xclient.message_type == display->atom_net_current_desktop) { @@ -942,6 +945,12 @@ event_callback (XEvent *event, else meta_verbose ("Don't know about workspace %d\n", space); } + else if (event->xclient.message_type == + display->atom_metacity_restart_message) + { + meta_verbose ("Received restart request\n"); + meta_restart (); + } } } break; diff --git a/src/display.h b/src/display.h index 80072c2af..0074b9cbf 100644 --- a/src/display.h +++ b/src/display.h @@ -101,6 +101,7 @@ struct _MetaDisplay Atom atom_kwm_win_icon; Atom atom_net_wm_moveresize; Atom atom_net_active_window; + Atom atom_metacity_restart_message; /* This is the actual window from focus events, * not the one we last set diff --git a/src/main.c b/src/main.c index a5eddb127..9d0d40299 100644 --- a/src/main.c +++ b/src/main.c @@ -34,9 +34,12 @@ #include #include #include +#include +#include static MetaExitCode meta_exit_code = META_EXIT_SUCCESS; static GMainLoop *meta_main_loop = NULL; +static gboolean meta_restart_after_quit = FALSE; static void log_handler (const gchar *log_domain, @@ -187,15 +190,40 @@ main (int argc, char **argv) { GSList *displays; GSList *tmp; - - displays = meta_displays_list (); + + /* we need a copy since closing the display removes it + * from the list + */ + displays = g_slist_copy (meta_displays_list ()); tmp = displays; while (tmp != NULL) { meta_display_close (tmp->data); tmp = tmp->next; } + g_slist_free (displays); } + + if (meta_restart_after_quit) + { + GError *err; + + err = NULL; + if (!g_spawn_async (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + NULL, + &err)) + { + meta_fatal (_("Failed to restart: %s\n"), + err->message); + g_error_free (err); /* not reached anyhow */ + meta_exit_code = META_EXIT_ERROR; + } + } return meta_exit_code; } @@ -222,3 +250,9 @@ meta_exit (MetaExitCode code) exit (code); } +void +meta_restart (void) +{ + meta_restart_after_quit = TRUE; + meta_quit (META_EXIT_SUCCESS); +} diff --git a/src/main.h b/src/main.h index a5db63484..cda080fec 100644 --- a/src/main.h +++ b/src/main.h @@ -36,6 +36,8 @@ void meta_exit (MetaExitCode code); /* g_main_quit() then fall out of main() */ void meta_quit (MetaExitCode code); +void meta_restart (void); + GMainLoop* meta_get_main_loop (void); #endif diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am new file mode 100644 index 000000000..0db4a6912 --- /dev/null +++ b/src/tools/Makefile.am @@ -0,0 +1,9 @@ + +INCLUDES=@METACITY_RESTART_CFLAGS@ + +metacity_restart_SOURCES= \ + metacity-restart.c + +bin_PROGRAMS=metacity-restart + +metacity_restart_LDADD= @METACITY_RESTART_LIBS@ diff --git a/src/tools/metacity-restart.c b/src/tools/metacity-restart.c new file mode 100644 index 000000000..c1eacbadf --- /dev/null +++ b/src/tools/metacity-restart.c @@ -0,0 +1,56 @@ +/* Metacity restart app */ + +/* + * 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 +#include + +int +main (int argc, char **argv) +{ + XEvent xev; + + gtk_init (&argc, &argv); + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = gdk_display; + xev.xclient.window = gdk_x11_get_default_root_xwindow (); + xev.xclient.message_type = XInternAtom (gdk_display, + "_METACITY_RESTART_MESSAGE", + False); + xev.xclient.format = 32; + xev.xclient.data.l[0] = 0; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + + XSendEvent (gdk_display, + gdk_x11_get_default_root_xwindow (), + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); + + XFlush (gdk_display); + XSync (gdk_display, False); + + return 0; +} +