From e5f444e9a8c050f16ab30f5cf696180ad8268479 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 11 Jul 2005 18:28:23 +0000 Subject: [PATCH] Make gdk_window_present() move the window to the current desktop, instead 2005-07-11 Matthias Clasen Make gdk_window_present() move the window to the current desktop, instead of letting the WM change the current desktop to where the window is. (#166379, Elijah Newren) * gdk/gdk.symbols: * gdk/x11/gdkx.h: * gdk/x11/gdkwindow-x11.c (gdk_x11_window_move_to_current_desktop): New function to move a window to the current desktop. * gtk/gtkwindow.c (gtk_window_present_with_time): Move the window to the current desktop before giving it focus. --- ChangeLog | 14 ++++++++ ChangeLog.pre-2-10 | 14 ++++++++ ChangeLog.pre-2-8 | 14 ++++++++ gdk/gdk.symbols | 1 + gdk/x11/gdkwindow-x11.c | 80 ++++++++++++++++++++++++++++++++++++----- gdk/x11/gdkx.h | 2 +- gtk/gtkwindow.c | 31 ++++++++-------- 7 files changed, 133 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b557e90be..a3d04a18d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2005-07-11 Matthias Clasen + + Make gdk_window_present() move the window to the current + desktop, instead of letting the WM change the current + desktop to where the window is. (#166379, Elijah Newren) + + * gdk/gdk.symbols: + * gdk/x11/gdkx.h: + * gdk/x11/gdkwindow-x11.c (gdk_x11_window_move_to_current_desktop): + New function to move a window to the current desktop. + + * gtk/gtkwindow.c (gtk_window_present_with_time): Move the + window to the current desktop before giving it focus. + 2005-07-11 Matthias Clasen When dragging text, use a drag icon showing the (ellipsized) diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 8b557e90be..a3d04a18d2 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,17 @@ +2005-07-11 Matthias Clasen + + Make gdk_window_present() move the window to the current + desktop, instead of letting the WM change the current + desktop to where the window is. (#166379, Elijah Newren) + + * gdk/gdk.symbols: + * gdk/x11/gdkx.h: + * gdk/x11/gdkwindow-x11.c (gdk_x11_window_move_to_current_desktop): + New function to move a window to the current desktop. + + * gtk/gtkwindow.c (gtk_window_present_with_time): Move the + window to the current desktop before giving it focus. + 2005-07-11 Matthias Clasen When dragging text, use a drag icon showing the (ellipsized) diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 8b557e90be..a3d04a18d2 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,17 @@ +2005-07-11 Matthias Clasen + + Make gdk_window_present() move the window to the current + desktop, instead of letting the WM change the current + desktop to where the window is. (#166379, Elijah Newren) + + * gdk/gdk.symbols: + * gdk/x11/gdkx.h: + * gdk/x11/gdkwindow-x11.c (gdk_x11_window_move_to_current_desktop): + New function to move a window to the current desktop. + + * gtk/gtkwindow.c (gtk_window_present_with_time): Move the + window to the current desktop before giving it focus. + 2005-07-11 Matthias Clasen When dragging text, use a drag icon showing the (ellipsized) diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index cfaf57af58..97f2522ece 100644 --- a/gdk/gdk.symbols +++ b/gdk/gdk.symbols @@ -1181,6 +1181,7 @@ gdkx_visual_get #if IN_FILE(__GDK_WINDOW_X11_C__) gdk_x11_window_set_user_time +gdk_x11_window_move_to_current_desktop #endif #if IN_FILE(__GDK_XID_C__) diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index d939a6345d..ca82cfc2de 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -2020,14 +2020,79 @@ gdk_window_lower (GdkWindow *window) XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); } +/** + * gdk_x11_window_move_to_current_desktop: + * @window: a #GdkWindow + * + * Moves the window to the correct workspace when running under a + * window manager that supports multiple workspaces, as described + * in the Extended + * Window Manager Hints. + * + * Since: 2.8 + */ +void +gdk_x11_window_move_to_current_desktop (GdkWindow *window) +{ + if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), + gdk_atom_intern ("_NET_WM_DESKTOP", FALSE))) + { + XEvent xev; + Atom type; + gint format; + gulong nitems; + gulong bytes_after; + guchar *data; + gulong *current_desktop; + GdkDisplay *display; + + display = gdk_drawable_get_display (window); + + /* Get current desktop, then set it; this is a race, but not + * one that matters much in practice. + */ + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XROOTWIN (window), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"), + 0, G_MAXLONG, + False, XA_CARDINAL, &type, &format, &nitems, + &bytes_after, &data); + + if (type == XA_CARDINAL) + { + current_desktop = (gulong *)data; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.window = GDK_WINDOW_XWINDOW (window); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"); + xev.xclient.format = 32; + + xev.xclient.data.l[0] = *current_desktop; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XROOTWIN (window), + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); + + XFree (current_desktop); + } + } +} + /** * gdk_window_focus: * @window: a #GdkWindow * @timestamp: timestamp of the event triggering the window focus * - * Sets keyboard focus to @window. If @window is not onscreen this - * will not work. In most cases, gtk_window_present() should be used on - * a #GtkWindow, rather than calling this function. + * Sets keyboard focus to @window. In most cases, gtk_window_present() + * should be used on a #GtkWindow, rather than calling this function. * **/ void @@ -5785,9 +5850,8 @@ emulate_move_drag (GdkWindow *window, * Begins a window resize operation (for a toplevel window). * You might use this function to implement a "window resize grip," for * example; in fact #GtkStatusbar uses it. The function works best - * with window managers that support the Extended Window Manager Hints spec - * (see http://www.freedesktop.org), but has a fallback implementation - * for other window managers. + * with window managers that support the Extended Window Manager Hints, but has a + * fallback implementation for other window managers. * **/ void @@ -5821,8 +5885,8 @@ gdk_window_begin_resize_drag (GdkWindow *window, * Begins a window move operation (for a toplevel window). You might * use this function to implement a "window move grip," for * example. The function works best with window managers that support - * the Extended Window Manager Hints spec (see - * http://www.freedesktop.org), but has a fallback implementation for + * the Extended + * Window Manager Hints, but has a fallback implementation for * other window managers. * **/ diff --git a/gdk/x11/gdkx.h b/gdk/x11/gdkx.h index ac6ee44421..1e9f1f1fb1 100644 --- a/gdk/x11/gdkx.h +++ b/gdk/x11/gdkx.h @@ -55,6 +55,7 @@ Screen * gdk_x11_screen_get_xscreen (GdkScreen *screen); int gdk_x11_screen_get_screen_number (GdkScreen *screen); void gdk_x11_window_set_user_time (GdkWindow *window, guint32 timestamp); +void gdk_x11_window_move_to_current_desktop (GdkWindow *window); const char* gdk_x11_screen_get_window_manager_name (GdkScreen *screen); @@ -154,7 +155,6 @@ gpointer gdk_xid_table_lookup (XID xid); gboolean gdk_net_wm_supports (GdkAtom property); void gdk_x11_grab_server (void); void gdk_x11_ungrab_server (void); - #endif GdkDisplay *gdk_x11_lookup_xdisplay (Display *xdisplay); diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 9811973344..8f0365c2dd 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -6007,17 +6007,7 @@ gtk_window_set_frame_dimensions (GtkWindow *window, void gtk_window_present (GtkWindow *window) { - guint32 timestamp; -#ifdef GDK_WINDOWING_X11 - GdkDisplay *display; - - display = gtk_widget_get_display (GTK_WIDGET (window)); - timestamp = gdk_x11_display_get_user_time (display); -#else - timestamp = gtk_get_current_event_time (); -#endif - - gtk_window_present_with_time (window, timestamp); + gtk_window_present_with_time (window, GDK_CURRENT_TIME); } /** @@ -6048,9 +6038,22 @@ gtk_window_present_with_time (GtkWindow *window, gdk_window_show (widget->window); - /* note that gdk_window_focus() will also move the window to - * the current desktop, for WM spec compliant window managers. - */ + /* Translate a timestamp of GDK_CURRENT_TIME appropriately */ + if (timestamp == GDK_CURRENT_TIME) + { +#ifdef GDK_WINDOWING_X11 + GdkDisplay *display; + + display = gtk_widget_get_display (GTK_WIDGET (window)); + timestamp = gdk_x11_display_get_user_time (display); +#else + timestamp = gtk_get_current_event_time (); +#endif + } + +#ifdef GDK_WINDOWING_X11 + gdk_x11_window_move_to_current_desktop (widget->window); +#endif gdk_window_focus (widget->window, timestamp); } else