From: Ira W. Snyder Date: Mon, 7 Apr 2008 21:14:52 +0000 (-0700) Subject: [Window] Fix focus with metacity-2.22 X-Git-Url: https://www.irasnyder.com/gitweb/?p=tilda-gobject.git;a=commitdiff_plain;h=1e9796f7b425e6d72ac10934045053b1692d42ca [Window] Fix focus with metacity-2.22 Metacity-2.22 broke our old hack to get the focus. This hack was suggested by the folks on GNOME's IRC channel. I left the old _NET_WM_USER_TIME hack in place, because it does not seem to cause any problems. It didn't seem to matter if I removed it either, though. Tested Window Managers: Metacity-2.20.2 Metacity-2.22.0 KWin-3.5.9 Fluxbox-1.0.0 Openbox-3.4.7_pre3 --- diff --git a/tilda-window.c b/tilda-window.c index d2ebc18..f26bfc3 100644 --- a/tilda-window.c +++ b/tilda-window.c @@ -246,6 +246,65 @@ tilda_window_center_vertically (TildaWindow *self) g_object_set (G_OBJECT(self), "y-position", center_coord, NULL); } +/* Shamelessly adapted (read: ripped off) from gdk_window_focus() and + * http://code.google.com/p/ttm/ trunk/src/window.c set_active() + * + * Also, more thanks to halfline and marnanel from irc.gnome.org #gnome + * for their help in figuring this out. + * + * Thank you. + */ + +/* This function will make sure that tilda window becomes active (gains + * the focus) when it is called. + * + * This has to be the worst possible way of making this work, but it was the + * only way to get metacity to play nicely. All the other WM's are so nice, + * why oh why does metacity hate us so? + */ +static void +tilda_window_set_active (TildaWindow *self) +{ + debug_enter (); + debug_assert (TILDA_IS_WINDOW(self)); + + Display *x11_display = GDK_WINDOW_XDISPLAY( self->window->window ); + Window *x11_window = GDK_WINDOW_XWINDOW( self->window->window ); + Window *x11_root_window = GDK_WINDOW_XWINDOW( gtk_widget_get_root_window (self->window) ); + GdkScreen *screen = gtk_widget_get_screen (self->window); + + XEvent event; + long mask = SubstructureRedirectMask | SubstructureNotifyMask; + + if (gdk_x11_screen_supports_net_wm_hint (screen, + gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW"))) + { + event.xclient.type = ClientMessage; + event.xclient.serial = 0; + event.xclient.send_event = True; + event.xclient.display = x11_display; + event.xclient.window = x11_window; + event.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"); + + event.xclient.format = 32; + event.xclient.data.l[0] = 2; /* pager */ + event.xclient.data.l[1] = tomboy_keybinder_get_current_event_time(); /* timestamp */ + event.xclient.data.l[2] = 0; + event.xclient.data.l[3] = 0; + event.xclient.data.l[4] = 0; + + XSendEvent (x11_display, x11_root_window, False, mask, &event); + } + else + { + /* The WM doesn't support the EWMH standards. We'll print a warning and + * try this, though it probably won't work... */ + g_printerr (_("WARNING: Window manager (%s) does not support EWMH hints\n"), + gdk_x11_screen_get_window_manager_name (screen)); + XRaiseWindow (x11_display, x11_window); + } +} + static void tilda_window_keybinding_cb (const gchar *keystr, gpointer data) { @@ -281,6 +340,9 @@ tilda_window_keybinding_cb (const gchar *keystr, gpointer data) NULL); gtk_widget_show (GTK_WIDGET(self->window)); + /* Bugfix: this code fixes metacity-2.22 */ + tilda_window_set_active (self); + /* Focusing the term here works perfectly, near as I can tell */ tt = tilda_window_find_current_terminal (self); gtk_widget_grab_focus (GTK_WIDGET(tt->vte_term));