[gnome-terminal] Save the desktop when unrealizing/realizing
- From: Owen Taylor <otaylor src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnome-terminal] Save the desktop when unrealizing/realizing
- Date: Tue, 23 Jun 2009 13:16:00 -0400 (EDT)
commit 6eb4c0d7de2ee9a3c27c7eb9905d186791f08626
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Thu Jun 18 16:52:18 2009 -0400
Save the desktop when unrealizing/realizing
Save the current desktop for a terminal window when unrealizing
and realizing it to change the colormap.
This is complicated because: a) GDK has no support for_NET_WM_DESKTOP
b) GDK however clears _NET_WM_DESKTOP on map (as part of it's
support for sticky windows.)
http://bugzilla.gnome.org/show_bug.cgi?id=564648
src/terminal-util.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++
src/terminal-util.h | 5 ++
src/terminal-window.c | 11 +++++
3 files changed, 132 insertions(+), 0 deletions(-)
---
diff --git a/src/terminal-util.c b/src/terminal-util.c
index a6bca92..587d1d7 100644
--- a/src/terminal-util.c
+++ b/src/terminal-util.c
@@ -32,6 +32,11 @@
#include <gio/gio.h>
#include <gtk/gtk.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+#endif
+
#include "terminal-accels.h"
#include "terminal-app.h"
#include "terminal-intl.h"
@@ -869,3 +874,114 @@ terminal_util_bind_object_property_to_widget (GObject *object,
change->object_notify_id = g_signal_connect_swapped (object, notify_signal, G_CALLBACK (object_change_notify_cb), change);
}
+#ifdef GDK_WINDOWING_X11
+
+/* We don't want to hop desktops when we unrealize/realize.
+ * So we need to save and restore the value of NET_WM_DESKTOP. This isn't
+ * exposed through GDK.
+ */
+gboolean
+terminal_util_x11_get_net_wm_desktop (GdkWindow *window,
+ guint32 *desktop)
+{
+ GdkDisplay *display = gdk_drawable_get_display (window);
+ Atom type;
+ int format;
+ guchar *data;
+ gulong n_items, bytes_after;
+ gboolean result = FALSE;
+
+ if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_DRAWABLE_XID (window),
+ gdk_x11_get_xatom_by_name_for_display (display,
+ "_NET_WM_DESKTOP"),
+ 0, G_MAXLONG, False, AnyPropertyType,
+ &type, &format, &n_items, &bytes_after, &data) == Success &&
+ type != None)
+ {
+ if (type == XA_CARDINAL && format == 32 && n_items == 1)
+ {
+ *desktop = *(gulong *)data;
+ result = TRUE;
+ }
+
+ XFree (data);
+ }
+
+ return result;
+}
+
+void
+terminal_util_x11_set_net_wm_desktop (GdkWindow *window,
+ guint32 desktop)
+{
+ /* We can't change the current desktop before mapping our window,
+ * because GDK has the annoying habit of clearing _NET_WM_DESKTOP
+ * before mapping a GdkWindow, So we we have to do it after instead.
+ *
+ * However, doing it after is different whether or not we have a
+ * window manager (if we don't have a window manager, we have to
+ * set the _NET_WM_DESKTOP property so that it picks it up when
+ * it starts)
+ *
+ * http://bugzilla.gnome.org/show_bug.cgi?id=586311 asks for GTK+
+ * to just handle everything behind the scenes including the desktop.
+ */
+ GdkScreen *screen = gdk_drawable_get_screen (window);
+ GdkDisplay *display = gdk_screen_get_display (screen);
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+ char *wm_selection_name;
+ Atom wm_selection;
+ gboolean have_wm;
+
+ wm_selection_name = g_strdup_printf ("WM_S%d", gdk_screen_get_number (screen));
+ wm_selection = gdk_x11_get_xatom_by_name_for_display (display, wm_selection_name);
+ g_free(wm_selection_name);
+
+ XGrabServer (xdisplay);
+
+ have_wm = XGetSelectionOwner (xdisplay, wm_selection) != None;
+
+ if (have_wm)
+ {
+ /* code borrowed from GDK
+ */
+ XClientMessageEvent xclient;
+
+ memset (&xclient, 0, sizeof (xclient));
+ xclient.type = ClientMessage;
+ xclient.serial = 0;
+ xclient.send_event = True;
+ xclient.window = GDK_WINDOW_XWINDOW (window);
+ xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP");
+ xclient.format = 32;
+
+ xclient.data.l[0] = desktop;
+ xclient.data.l[1] = 0;
+ xclient.data.l[2] = 0;
+ xclient.data.l[3] = 0;
+ xclient.data.l[4] = 0;
+
+ XSendEvent (xdisplay,
+ GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen)),
+ False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ (XEvent *)&xclient);
+ }
+ else
+ {
+ gulong long_desktop = desktop;
+
+ XChangeProperty (xdisplay,
+ GDK_DRAWABLE_XID (window),
+ gdk_x11_get_xatom_by_name_for_display (display,
+ "_NET_WM_DESKTOP"),
+ XA_CARDINAL, 32, PropModeReplace,
+ (guchar *)&long_desktop, 1);
+ }
+
+ XUngrabServer (xdisplay);
+ XFlush (xdisplay);
+}
+
+#endif /* GDK_WINDOWING_X11 */
diff --git a/src/terminal-util.h b/src/terminal-util.h
index d72fba1..acfd437 100644
--- a/src/terminal-util.h
+++ b/src/terminal-util.h
@@ -100,4 +100,9 @@ void terminal_util_bind_object_property_to_widget (GObject *object,
GtkWidget *widget,
PropertyChangeFlags flags);
+gboolean terminal_util_x11_get_net_wm_desktop (GdkWindow *window,
+ guint32 *desktop);
+void terminal_util_x11_set_net_wm_desktop (GdkWindow *window,
+ guint32 desktop);
+
#endif /* TERMINAL_UTIL_H */
diff --git a/src/terminal-window.c b/src/terminal-window.c
index 470189b..95db45a 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -22,7 +22,9 @@
#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
+#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
+#endif
#include <gdk/gdkkeysyms.h>
#include <libsn/sn-launchee.h>
@@ -1482,6 +1484,8 @@ terminal_window_composited_changed_cb (GdkScreen *screen,
{
GtkWidget *widget = GTK_WIDGET (window);
guint32 user_time;
+ gboolean have_desktop;
+ guint32 desktop = 0; /* Quiet GCC */
int x, y;
user_time = gdk_x11_display_get_user_time (gtk_widget_get_display (widget));
@@ -1494,6 +1498,10 @@ terminal_window_composited_changed_cb (GdkScreen *screen,
* framing our window, so we might see a funky intermediate state.
* But at worst, we'll be off by a few pixels (the frame size). */
gtk_window_get_position (GTK_WINDOW (window), &x, &y);
+
+ /* And the desktop */
+ have_desktop = terminal_util_x11_get_net_wm_desktop (widget->window, &desktop);
+
gtk_widget_hide (widget);
gtk_widget_unrealize (widget);
@@ -1501,7 +1509,10 @@ terminal_window_composited_changed_cb (GdkScreen *screen,
gtk_window_move (GTK_WINDOW (window), x, y);
gtk_widget_realize (widget);
gdk_x11_window_set_user_time (widget->window, user_time);
+
gtk_widget_show (widget);
+ if (have_desktop)
+ terminal_util_x11_set_net_wm_desktop (widget->window, desktop);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]