[gtk+] x11: Add EWMH workspace handling api
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] x11: Add EWMH workspace handling api
- Date: Sat, 24 Aug 2013 04:53:26 +0000 (UTC)
commit 13f6552a7ea771638240f394c495c977e33533d0
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Aug 24 00:51:01 2013 -0400
x11: Add EWMH workspace handling api
Add a few functions that give access to the EWMH workspace
properties.
docs/reference/gdk/gdk3-sections.txt | 4 +
gdk/x11/gdkscreen-x11.c | 71 +++++++++++++++++
gdk/x11/gdkwindow-x11.c | 139 ++++++++++++++++++++++------------
gdk/x11/gdkx11screen.h | 5 +
gdk/x11/gdkx11window.h | 6 ++
5 files changed, 175 insertions(+), 50 deletions(-)
---
diff --git a/docs/reference/gdk/gdk3-sections.txt b/docs/reference/gdk/gdk3-sections.txt
index 365244c..634c2c1 100644
--- a/docs/reference/gdk/gdk3-sections.txt
+++ b/docs/reference/gdk/gdk3-sections.txt
@@ -998,6 +998,8 @@ gdk_x11_screen_get_window_manager_name
gdk_x11_screen_get_monitor_output
gdk_x11_screen_lookup_visual
gdk_x11_screen_supports_net_wm_hint
+gdk_x11_screen_get_number_of_desktops
+gdk_x11_screen_get_current_desktop
gdk_x11_window_foreign_new_for_display
gdk_x11_window_lookup_for_display
gdk_x11_window_get_xid
@@ -1005,6 +1007,8 @@ gdk_x11_window_set_hide_titlebar_when_maximized
gdk_x11_window_set_theme_variant
gdk_x11_window_set_user_time
gdk_x11_window_move_to_current_desktop
+gdk_x11_window_move_to_desktop
+gdk_x11_window_get_desktop
gdk_x11_window_set_utf8_property
gdk_x11_get_default_root_xwindow
gdk_x11_get_default_screen
diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c
index 9f2f833..c2d7c88 100644
--- a/gdk/x11/gdkscreen-x11.c
+++ b/gdk/x11/gdkscreen-x11.c
@@ -1722,3 +1722,74 @@ gdk_x11_screen_class_init (GdkX11ScreenClass *klass)
G_TYPE_NONE,
0);
}
+
+static guint32
+get_netwm_cardinal_property (GdkScreen *screen,
+ const gchar *name)
+{
+ GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
+ GdkAtom atom;
+ guint32 prop = 0;
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+ guchar *data;
+
+ atom = gdk_atom_intern_static_string (name);
+
+ if (!gdk_x11_screen_supports_net_wm_hint (screen, atom))
+ return 0;
+
+ XGetWindowProperty (x11_screen->xdisplay,
+ x11_screen->xroot_window,
+ gdk_x11_get_xatom_by_name_for_display (GDK_SCREEN_DISPLAY (screen), name),
+ 0, G_MAXLONG,
+ False, XA_CARDINAL, &type, &format, &nitems,
+ &bytes_after, &data);
+ if (type == XA_CARDINAL)
+ {
+ prop = *(gulong *)data;
+ XFree (data);
+ }
+
+ return prop;
+}
+
+/**
+ * gdk_x11_screen_get_number_of_desktops:
+ * @screen: a #GdkScreen
+ *
+ * Returns the number of workspaces for @screen when running under a
+ * window manager that supports multiple workspaces, as described
+ * in the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
+ * Window Manager Hints</ulink>.
+ *
+ * Returns: the number of workspaces, or 0 if workspaces are not supported
+ *
+ * Since: 3.10
+ */
+guint32
+gdk_x11_screen_get_number_of_desktops (GdkScreen *screen)
+{
+ return get_netwm_cardinal_property (screen, "_NET_NUMBER_OF_DESKTOPS");
+}
+
+/**
+ * gdk_x11_screen_get_current_desktop:
+ * @screen: a #GdkScreen
+ *
+ * Returns the current workspace for @screen when running under a
+ * window manager that supports multiple workspaces, as described
+ * in the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
+ * Window Manager Hints</ulink>.
+ *
+ * Returns: the current workspace, or 0 if workspaces are not supported
+ *
+ * Since: 3.10
+ */
+guint32
+gdk_x11_screen_get_current_desktop (GdkScreen *screen)
+{
+ return get_netwm_cardinal_property (screen, "_NET_CURRENT_DESKTOP");
+}
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index d4ce45c..4dc632f 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -2116,59 +2116,98 @@ gdk_x11_window_move_to_current_desktop (GdkWindow *window)
static void
move_to_current_desktop (GdkWindow *window)
{
- if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
- gdk_atom_intern_static_string ("_NET_WM_DESKTOP")) &&
- gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
- gdk_atom_intern_static_string ("_NET_CURRENT_DESKTOP")))
- {
- Atom type;
- gint format;
- gulong nitems;
- gulong bytes_after;
- guchar *data;
- gulong *current_desktop;
- GdkDisplay *display;
-
- display = gdk_window_get_display (window);
+ guint32 desktop;
- /* 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)
- {
- XClientMessageEvent xclient;
- current_desktop = (gulong *)data;
-
- memset (&xclient, 0, sizeof (xclient));
- xclient.type = ClientMessage;
- xclient.serial = 0;
- xclient.send_event = True;
- xclient.window = GDK_WINDOW_XID (window);
- xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP");
- xclient.format = 32;
-
- xclient.data.l[0] = *current_desktop;
- xclient.data.l[1] = 1; /* source indication */
- xclient.data.l[2] = 0;
- xclient.data.l[3] = 0;
- xclient.data.l[4] = 0;
-
- XSendEvent (GDK_DISPLAY_XDISPLAY (display),
- GDK_WINDOW_XROOTWIN (window),
- False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- (XEvent *)&xclient);
+ desktop = gdk_x11_screen_get_current_desktop (GDK_WINDOW_SCREEN (window));
+ gdk_x11_window_move_to_desktop (window, desktop);
+}
- XFree (current_desktop);
- }
+static guint32
+get_netwm_cardinal_property (GdkWindow *window,
+ const gchar *name)
+{
+ GdkScreen *screen = GDK_WINDOW_SCREEN (window);
+ GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
+ GdkAtom atom;
+ guint32 prop = 0;
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+ guchar *data;
+
+ atom = gdk_atom_intern_static_string (name);
+
+ if (!gdk_x11_screen_supports_net_wm_hint (screen, atom))
+ return 0;
+
+ XGetWindowProperty (x11_screen->xdisplay,
+ GDK_WINDOW_XID (window),
+ gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), name),
+ 0, G_MAXLONG,
+ False, XA_CARDINAL, &type, &format, &nitems,
+ &bytes_after, &data);
+ if (type == XA_CARDINAL)
+ {
+ prop = *(gulong *)data;
+ XFree (data);
}
+
+ return prop;
+}
+
+guint32
+gdk_x11_window_get_desktop (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ return get_netwm_cardinal_property (window, "_NET_WM_DESKTOP");
+}
+
+/**
+ * gdk_x11_window_move_to_desktop:
+ * @window: a #GdkWindow
+ * @desktop: the number of the workspace to move the window to
+ *
+ * Moves the window to the given workspace when running unde a
+ * window manager that supports multiple workspaces, as described
+ * in the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
+ * Window Manager Hints</ulink>.
+ *
+ * Since: 3.10
+ */
+void
+gdk_x11_window_move_to_desktop (GdkWindow *window,
+ guint32 desktop)
+{
+ GdkAtom atom;
+ XClientMessageEvent xclient;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ atom = gdk_atom_intern_static_string ("_NET_WM_DESKTOP");
+ if (!gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), atom))
+ return;
+
+ memset (&xclient, 0, sizeof (xclient));
+ xclient.type = ClientMessage;
+ xclient.serial = 0;
+ xclient.send_event = True;
+ xclient.window = GDK_WINDOW_XID (window);
+ xclient.message_type = gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (window), atom);
+ xclient.format = 32;
+
+ xclient.data.l[0] = desktop;
+ xclient.data.l[1] = 1; /* source indication */
+ xclient.data.l[2] = 0;
+ xclient.data.l[3] = 0;
+ xclient.data.l[4] = 0;
+
+ XSendEvent (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XROOTWIN (window),
+ False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ (XEvent *)&xclient);
}
static void
diff --git a/gdk/x11/gdkx11screen.h b/gdk/x11/gdkx11screen.h
index efc7d38..8f91d64 100644
--- a/gdk/x11/gdkx11screen.h
+++ b/gdk/x11/gdkx11screen.h
@@ -104,6 +104,11 @@ GDK_AVAILABLE_IN_ALL
XID gdk_x11_screen_get_monitor_output (GdkScreen *screen,
gint monitor_num);
+GDK_AVAILABLE_IN_3_10
+guint32 gdk_x11_screen_get_number_of_desktops (GdkScreen *screen);
+GDK_AVAILABLE_IN_3_10
+guint32 gdk_x11_screen_get_current_desktop (GdkScreen *screen);
+
G_END_DECLS
#endif /* __GDK_X11_SCREEN_H__ */
diff --git a/gdk/x11/gdkx11window.h b/gdk/x11/gdkx11window.h
index 24bb853..8e8290c 100644
--- a/gdk/x11/gdkx11window.h
+++ b/gdk/x11/gdkx11window.h
@@ -77,6 +77,12 @@ void gdk_x11_window_set_hide_titlebar_when_maximized (GdkWindow *window,
GDK_AVAILABLE_IN_ALL
void gdk_x11_window_move_to_current_desktop (GdkWindow *window);
+GDK_AVAILABLE_IN_3_10
+guint32 gdk_x11_window_get_desktop (GdkWindow *window);
+GDK_AVAILABLE_IN_3_10
+void gdk_x11_window_move_to_desktop (GdkWindow *window,
+ guint32 desktop);
+
GDK_AVAILABLE_IN_3_8
void gdk_x11_window_set_frame_sync_enabled (GdkWindow *window,
gboolean frame_sync_enabled);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]