[Xfce4-commits] [apps/xfdashboard] 03/19: Added GDK (for X11) window tracker backend

noreply at xfce.org noreply at xfce.org
Fri Jun 16 10:56:34 CEST 2017


This is an automated email from the git hooks/post-receive script.

n   o   m   a   d       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository apps/xfdashboard.

commit 2adf25ead816b302001360ce541a9f5f26add783
Author: Stephan Haller <nomad at froevel.de>
Date:   Tue Jun 13 07:37:54 2017 +0200

    Added GDK (for X11) window tracker backend
    
    Enhancement for issue GH #129
---
 libxfdashboard/Makefile.am                      |   2 +
 libxfdashboard/gdk/window-tracker-backend-gdk.c | 659 ++++++++++++++++++++++++
 libxfdashboard/gdk/window-tracker-backend-gdk.h |  74 +++
 3 files changed, 735 insertions(+)

diff --git a/libxfdashboard/Makefile.am b/libxfdashboard/Makefile.am
index bc1097e..3c6197d 100644
--- a/libxfdashboard/Makefile.am
+++ b/libxfdashboard/Makefile.am
@@ -253,6 +253,7 @@ endif
 gdk_headers = \
 	gdk/window-content-gdk.h \
 	gdk/window-tracker-gdk.h \
+	gdk/window-tracker-backend-gdk.h \
 	gdk/window-tracker-monitor-gdk.h \
 	gdk/window-tracker-window-gdk.h \
 	gdk/window-tracker-workspace-gdk.h
@@ -260,6 +261,7 @@ gdk_headers = \
 gdk_sources = \
 	gdk/window-content-gdk.c \
 	gdk/window-tracker-gdk.c \
+	gdk/window-tracker-backend-gdk.c \
 	gdk/window-tracker-monitor-gdk.c \
 	gdk/window-tracker-window-gdk.c \
 	gdk/window-tracker-workspace-gdk.c
diff --git a/libxfdashboard/gdk/window-tracker-backend-gdk.c b/libxfdashboard/gdk/window-tracker-backend-gdk.c
new file mode 100644
index 0000000..debf321
--- /dev/null
+++ b/libxfdashboard/gdk/window-tracker-backend-gdk.c
@@ -0,0 +1,659 @@
+/*
+ * window-tracker-backend: Window tracker backend providing special functions
+ *                         for different windowing and clutter backends.
+ * 
+ * Copyright 2012-2016 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libxfdashboard/gdk/window-tracker-backend-gdk.h>
+
+#include <glib/gi18n-lib.h>
+#include <clutter/gdk/clutter-gdk.h>
+#include <clutter/x11/clutter-x11.h>
+#include <gdk/gdkx.h>
+#ifdef HAVE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+
+#include <libxfdashboard/x11/window-tracker-x11.h>
+#include <libxfdashboard/x11/window-tracker-window-x11.h>
+#include <libxfdashboard/marshal.h>
+#include <libxfdashboard/compat.h>
+#include <libxfdashboard/debug.h>
+
+
+/* Define this class in GObject system */
+static void _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_iface_init(XfdashboardWindowTrackerBackendInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(XfdashboardWindowTrackerBackendGDK,
+						xfdashboard_window_tracker_backend_gdk,
+						G_TYPE_OBJECT,
+						G_IMPLEMENT_INTERFACE(XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND, _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_iface_init))
+
+
+/* Private structure - access only by public API if needed */
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK_GET_PRIVATE(obj)                \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK, XfdashboardWindowTrackerBackendGDKPrivate))
+
+struct _XfdashboardWindowTrackerBackendGDKPrivate
+{
+	/* Instance related */
+	XfdashboardWindowTrackerX11		*windowTracker;
+};
+
+
+/* IMPLEMENTATION: Private variables and methods */
+
+/* State of stage window changed */
+static void _xfdashboard_window_tracker_backend_gdk_on_stage_state_changed(WnckWindow *inWindow,
+																			WnckWindowState inChangedMask,
+																			WnckWindowState inNewValue,
+																			gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11			*stageWindow;
+
+	g_return_if_fail(WNCK_IS_WINDOW(inWindow));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	stageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	/* Set 'skip-tasklist' if changed */
+	if((inChangedMask & WNCK_WINDOW_STATE_SKIP_TASKLIST) &&
+		!(inNewValue & WNCK_WINDOW_STATE_SKIP_TASKLIST))
+	{
+		wnck_window_set_skip_tasklist(WNCK_WINDOW(inWindow), TRUE);
+		XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+							"State 'skip-tasklist' for stage window %p (wnck-window=%p) needs reset",
+							stageWindow,
+							inWindow);
+	}
+
+	/* Set 'skip-pager' if changed */
+	if((inChangedMask & WNCK_WINDOW_STATE_SKIP_PAGER) &&
+		!(inNewValue & WNCK_WINDOW_STATE_SKIP_PAGER))
+	{
+		wnck_window_set_skip_pager(WNCK_WINDOW(inWindow), TRUE);
+		XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+							"State 'skip-pager' for stage window %p (wnck-window=%p) needs reset",
+							stageWindow,
+							inWindow);
+	}
+
+	/* Set 'make-above' if changed */
+	if((inChangedMask & WNCK_WINDOW_STATE_ABOVE) &&
+		!(inNewValue & WNCK_WINDOW_STATE_ABOVE))
+	{
+		wnck_window_make_above(WNCK_WINDOW(inWindow));
+		XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+							"State 'make-above' for stage window %p (wnck-window=%p) needs reset",
+							stageWindow,
+							inWindow);
+	}
+}
+
+/* The active window changed. Reselect stage window as active one if it is visible */
+static void _xfdashboard_window_tracker_backend_gdk_on_stage_active_window_changed(WnckScreen *inScreen,
+																					WnckWindow *inPreviousWindow,
+																					gpointer inUserData)
+{
+	XfdashboardWindowTrackerWindowX11			*stageWindow;
+	XfdashboardWindowTrackerWindowState			stageWindowState;
+	WnckWindow									*stageWnckWindow;
+	WnckWindow									*activeWindow;
+	gboolean									reselect;
+
+	g_return_if_fail(WNCK_IS_SCREEN(inScreen));
+	g_return_if_fail(inPreviousWindow==NULL || WNCK_IS_WINDOW(inPreviousWindow));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	stageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+	reselect=FALSE;
+
+	/* Get wnck window of stage window */
+	stageWnckWindow=xfdashboard_window_tracker_window_x11_get_window(stageWindow);
+	if(!stageWnckWindow)
+	{
+		g_critical(_("Could not get real stage window to handle signal 'active-window-changed'"));
+		return;
+	}
+
+	/* Get stage of stage window */
+	stageWindowState=xfdashboard_window_tracker_window_get_state(XFDASHBOARD_WINDOW_TRACKER_WINDOW(stageWindow));
+
+	/* Reactive stage window if not hidden */
+	activeWindow=wnck_screen_get_active_window(inScreen);
+
+	if(inPreviousWindow && inPreviousWindow==stageWnckWindow) reselect=TRUE;
+	if(!activeWindow || activeWindow!=stageWnckWindow) reselect=TRUE;
+	if(!(stageWindowState & (XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MINIMIZED | XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_HIDDEN))) reselect=TRUE;
+
+	if(reselect)
+	{
+		wnck_window_activate_transient(stageWnckWindow, xfdashboard_window_tracker_x11_get_time());
+		XFDASHBOARD_DEBUG(stageWindow, WINDOWS,
+							"Active window changed from %p (%s) to %p (%s) but stage window %p (wnck-window=%p) is visible and should be active one",
+							inPreviousWindow, inPreviousWindow ? wnck_window_get_name(inPreviousWindow) : "<nil>",
+							activeWindow, activeWindow ? wnck_window_get_name(activeWindow) : "<nil>",
+							stageWindow,
+							stageWnckWindow);
+	}
+}
+
+/* Size of screen has changed so resize stage window */
+static void _xfdashboard_window_tracker_backend_gdk_on_stage_screen_size_changed(XfdashboardWindowTracker *inWindowTracker,
+																					gint inWidth,
+																					gint inHeight,
+																					gpointer inUserData)
+{
+#ifdef HAVE_XINERAMA
+	XfdashboardWindowTrackerWindowX11	*realStageWindow;
+	WnckWindow							*stageWindow;
+	GdkDisplay							*display;
+	GdkScreen							*screen;
+	XineramaScreenInfo					*monitors;
+	int									monitorsCount;
+	gint								top, bottom, left, right;
+	gint								topIndex, bottomIndex, leftIndex, rightIndex;
+	gint								i;
+	Atom								atomFullscreenMonitors;
+	XEvent								xEvent;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(inWindowTracker));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	realStageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS, "Set fullscreen across all monitors using Xinerama");
+
+	/* Get wnck window for stage window object as it is needed a lot from this
+	 * point on.
+	 */
+	stageWindow=xfdashboard_window_tracker_window_x11_get_window(realStageWindow);
+
+	/* If window manager does not support fullscreen across all monitors
+	 * return here.
+	 */
+	if(!wnck_screen_net_wm_supports(wnck_window_get_screen(stageWindow), "_NET_WM_FULLSCREEN_MONITORS"))
+	{
+		g_warning(_("Keep window fullscreen on primary monitor because window manager does not support _NET_WM_FULLSCREEN_MONITORS."));
+		return;
+	}
+
+	/* Get display */
+	display=gdk_display_get_default();
+
+	/* Get screen */
+	screen=gdk_screen_get_default();
+
+	/* Check if Xinerama is active on display. If not try to move and resize
+	 * stage window to primary monitor.
+	 */
+	if(!XineramaIsActive(gdk_x11_display_get_xdisplay(display)))
+	{
+#if GTK_CHECK_VERSION(3, 22, 0)
+		GdkMonitor			*primaryMonitor;
+#else
+		gint				primaryMonitor;
+#endif
+		GdkRectangle		geometry;
+
+		/* Get position and size of primary monitor and try to move and resize
+		 * stage window to its position and size. Even if it fails it should
+		 * resize the stage to the size of current monitor this window is
+		 * fullscreened to. Tested with xfwm4.
+		 */
+#if GTK_CHECK_VERSION(3, 22, 0)
+		primaryMonitor=gdk_display_get_primary_monitor(gdk_screen_get_display(screen));
+		gdk_monitor_get_geometry(primaryMonitor, &geometry);
+#else
+		primaryMonitor=gdk_screen_get_primary_monitor(screen);
+		gdk_screen_get_monitor_geometry(screen, primaryMonitor, &geometry);
+#endif
+		wnck_window_set_geometry(stageWindow,
+									WNCK_WINDOW_GRAVITY_STATIC,
+									WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y | WNCK_WINDOW_CHANGE_WIDTH | WNCK_WINDOW_CHANGE_HEIGHT,
+									geometry.x, geometry.y, geometry.width, geometry.height);
+		return;
+	}
+
+	/* Get monitors from Xinerama */
+	monitors=XineramaQueryScreens(GDK_DISPLAY_XDISPLAY(display), &monitorsCount);
+	if(monitorsCount<=0 || !monitors)
+	{
+		if(monitors) XFree(monitors);
+		return;
+	}
+
+	/* Get monitor indices for each corner of screen */
+	xfdashboard_window_tracker_get_screen_size(inWindowTracker, &left, &top);
+	bottom=0;
+	right=0;
+	topIndex=bottomIndex=leftIndex=rightIndex=0;
+	for(i=0; i<monitorsCount; i++)
+	{
+		XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS,
+							"Checking edges at monitor %d with upper-left at %d,%d and lower-right at %d,%d [size: %dx%d]",
+							i,
+							monitors[i].x_org,
+							monitors[i].y_org,
+							monitors[i].x_org+monitors[i].width, monitors[i].y_org+monitors[i].height,
+							monitors[i].width, monitors[i].height);
+
+		if(left>monitors[i].x_org)
+		{
+			left=monitors[i].x_org;
+			leftIndex=i;
+		}
+
+		if(right<(monitors[i].x_org+monitors[i].width))
+		{
+			right=(monitors[i].x_org+monitors[i].width);
+			rightIndex=i;
+		}
+
+		if(top>monitors[i].y_org)
+		{
+			top=monitors[i].y_org;
+			topIndex=i;
+		}
+
+		if(bottom<(monitors[i].y_org+monitors[i].height))
+		{
+			bottom=(monitors[i].y_org+monitors[i].height);
+			bottomIndex=i;
+		}
+	}
+	XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS,
+						"Found edge monitors: left=%d (monitor %d), right=%d (monitor %d), top=%d (monitor %d), bottom=%d (monitor %d)",
+						left, leftIndex,
+						right, rightIndex,
+						top, topIndex,
+						bottom, bottomIndex);
+
+	/* Get X atom for fullscreen-across-all-monitors */
+	atomFullscreenMonitors=XInternAtom(gdk_x11_display_get_xdisplay(display),
+										"_NET_WM_FULLSCREEN_MONITORS",
+										False);
+
+	/* Send event to X to set window to fullscreen over all monitors */
+	memset(&xEvent, 0, sizeof(xEvent));
+	xEvent.type=ClientMessage;
+	xEvent.xclient.window=wnck_window_get_xid(stageWindow);
+	xEvent.xclient.display=GDK_DISPLAY_XDISPLAY(display);
+	xEvent.xclient.message_type=atomFullscreenMonitors;
+	xEvent.xclient.format=32;
+	xEvent.xclient.data.l[0]=topIndex;
+	xEvent.xclient.data.l[1]=bottomIndex;
+	xEvent.xclient.data.l[2]=leftIndex;
+	xEvent.xclient.data.l[3]=rightIndex;
+	xEvent.xclient.data.l[4]=0;
+	XSendEvent(GDK_DISPLAY_XDISPLAY(display),
+				DefaultRootWindow(GDK_DISPLAY_XDISPLAY(display)),
+				False,
+				SubstructureRedirectMask | SubstructureNotifyMask,
+				&xEvent);
+
+	/* Release allocated resources */
+	if(monitors) XFree(monitors);
+#else
+	XfdashboardWindowTrackerWindowX11	*realStageWindow;
+	WnckWindow							*stageWindow;
+	GdkScreen							*screen;
+	gint								primaryMonitor;
+	GdkRectangle						geometry;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(inWindowTracker));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+	realStageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+	XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS, "No support for multiple monitor: Setting fullscreen on primary monitor");
+
+	/* Get wnck window for stage window object as it is needed a lot from this
+	 * point on.
+	 */
+	stageWindow=xfdashboard_window_tracker_window_gdk_get_window(realStageWindow);
+
+	/* Get screen */
+	screen=gdk_screen_get_default();
+
+	/* Get position and size of primary monitor and try to move and resize
+	 * stage window to its position and size. Even if it fails it should
+	 * resize the stage to the size of current monitor this window is
+	 * fullscreened to. Tested with xfwm4.
+	 */
+	primaryMonitor=gdk_screen_get_primary_monitor(screen);
+	gdk_screen_get_monitor_geometry(screen, primaryMonitor, &geometry);
+	wnck_window_set_geometry(stageWindow,
+								WNCK_WINDOW_GRAVITY_STATIC,
+								WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y | WNCK_WINDOW_CHANGE_WIDTH | WNCK_WINDOW_CHANGE_HEIGHT,
+								geometry.x, geometry.y, geometry.width, geometry.height);
+
+	XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS,
+						"Moving stage window to %d,%d and resize to %dx%d",
+						geometry.x, geometry.y,
+						geometry.width, geometry.height);
+#endif
+}
+
+
+/* IMPLEMENTATION: XfdashboardWindowTrackerBackend */
+
+/* Get name of backend */
+static const gchar* _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_get_name(XfdashboardWindowTrackerBackend *inBackend)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK(inBackend), NULL);
+
+	/* Return name of backend */
+	return("GDK-X11");
+}
+
+/* Get window tracker instance used by this backend */
+static XfdashboardWindowTracker* _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_get_window_tracker(XfdashboardWindowTrackerBackend *inBackend)
+{
+	XfdashboardWindowTrackerBackendGDK				*self;
+	XfdashboardWindowTrackerBackendGDKPrivate		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK(inBackend), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK(inBackend);
+	priv=self->priv;
+
+	/* Return window tracker instance used by this instance but do not take a
+	 * reference on it as it will be done by the backend interface when
+	 * xfdashboard_window_tracker_backend_get_default() is called.
+	 */
+	return(XFDASHBOARD_WINDOW_TRACKER(priv->windowTracker));
+}
+
+/* Set up and show window for use as stage */
+static void _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_show_stage_window(XfdashboardWindowTrackerBackend *inBackend,
+																								XfdashboardWindowTrackerWindow *inStageWindow)
+{
+	XfdashboardWindowTrackerBackendGDK			*self;
+	XfdashboardWindowTrackerBackendGDKPrivate	*priv;
+	XfdashboardWindowTrackerWindowX11			*stageWindow;
+	GdkWindow									*stageGdkWindow;
+	WnckWindow									*stageWnckWindow;
+	WnckScreen									*screen;
+	guint										signalID;
+	gulong										handlerID;
+	gint										width, height;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK(inBackend));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inStageWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK(inBackend);
+	priv=self->priv;
+	stageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inStageWindow);
+
+	/* Get GDK stage window */
+	stageGdkWindow=clutter_gdk_get_stage_window(xfdashboard_window_tracker_window_get_stage(inStageWindow));
+	if(!stageGdkWindow)
+	{
+		g_critical(_("Could not get real stage window to show"));
+		return;
+	}
+
+	/* Window of stage should always be above all other windows, pinned to all
+	 * workspaces, not be listed in window pager and set to fullscreen
+	 */
+	gdk_window_set_skip_taskbar_hint(stageGdkWindow, TRUE);
+	gdk_window_set_skip_pager_hint(stageGdkWindow, TRUE);
+	gdk_window_set_keep_above(stageGdkWindow, TRUE);
+	gdk_window_stick(stageGdkWindow);
+#if GTK_CHECK_VERSION(3, 8, 0)
+	gdk_window_set_fullscreen_mode(stageGdkWindow, GDK_FULLSCREEN_ON_ALL_MONITORS);
+#endif
+	gdk_window_fullscreen(stageGdkWindow);
+
+	/* Get wnck window and screen of window */
+	stageWnckWindow=wnck_window_get(gdk_x11_window_get_xid(stageGdkWindow));
+	screen=wnck_window_get_screen(stageWnckWindow);
+
+	/* Connect signals if not already connected */
+	signalID=g_signal_lookup("state-changed", WNCK_TYPE_WINDOW);
+	handlerID=g_signal_handler_find(stageWnckWindow,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_state_changed),
+									NULL);
+	if(!handlerID)
+	{
+		g_signal_connect(stageWnckWindow,
+							"state-changed",
+							G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_state_changed),
+							stageWindow);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Connecting signal to 'state-changed' at window %p (wnck-window=%p)",
+							stageWindow,
+							stageWnckWindow);
+	}
+
+	signalID=g_signal_lookup("active-window-changed", WNCK_TYPE_SCREEN);
+	handlerID=g_signal_handler_find(screen,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_active_window_changed),
+									NULL);
+	if(!handlerID)
+	{
+		g_signal_connect(screen,
+							"active-window-changed",
+							G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_active_window_changed),
+							self);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Connecting signal to 'active-window-changed' at screen %p of window %p (wnck-window=%p)",
+							screen,
+							stageWindow,
+							stageWnckWindow);
+	}
+
+	signalID=g_signal_lookup("screen-size-changed", XFDASHBOARD_TYPE_WINDOW_TRACKER);
+	handlerID=g_signal_handler_find(priv->windowTracker,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_screen_size_changed),
+									NULL);
+	if(!handlerID)
+	{
+		g_signal_connect(priv->windowTracker,
+							"screen-size-changed",
+							G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_screen_size_changed),
+							self);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Connecting signal to 'screen-size-changed' at window %p (wnck-window=%p)",
+							stageWindow,
+							stageWnckWindow);
+	}
+	xfdashboard_window_tracker_get_screen_size(XFDASHBOARD_WINDOW_TRACKER(priv->windowTracker), &width, &height);
+	_xfdashboard_window_tracker_backend_gdk_on_stage_screen_size_changed(XFDASHBOARD_WINDOW_TRACKER(priv->windowTracker),
+																			width,
+																			height,
+																			self);
+
+	/* Now the window is set up and we can show it */
+	xfdashboard_window_tracker_window_show(inStageWindow);
+}
+
+/* Unset up and hide stage window */
+static void _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_hide_stage_window(XfdashboardWindowTrackerBackend *inBackend,
+																								XfdashboardWindowTrackerWindow *inStageWindow)
+{
+	XfdashboardWindowTrackerBackendGDK			*self;
+	XfdashboardWindowTrackerBackendGDKPrivate	*priv;
+	XfdashboardWindowTrackerWindowX11			*stageWindow;
+	GdkWindow									*stageGdkWindow;
+	WnckWindow									*stageWnckWindow;
+	WnckScreen									*screen;
+	guint										signalID;
+	gulong										handlerID;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK(inBackend));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inStageWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK(inBackend);
+	priv=self->priv;
+	stageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inStageWindow);
+
+	/* Get GDK stage window */
+	stageGdkWindow=clutter_gdk_get_stage_window(xfdashboard_window_tracker_window_get_stage(inStageWindow));
+	if(!stageGdkWindow)
+	{
+		g_critical(_("Could not get real stage window to show"));
+		return;
+	}
+
+	/* First hide window before removing signals etc. */
+	xfdashboard_window_tracker_window_hide(inStageWindow);
+
+	/* Get wnck window and screen of window */
+	stageWnckWindow=wnck_window_get(gdk_x11_window_get_xid(stageGdkWindow));
+	screen=wnck_window_get_screen(stageWnckWindow);
+
+	/* Disconnect signals */
+	signalID=g_signal_lookup("state-changed", WNCK_TYPE_WINDOW);
+	handlerID=g_signal_handler_find(stageWnckWindow,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_state_changed),
+									NULL);
+	if(handlerID)
+	{
+		g_signal_handler_disconnect(stageWnckWindow, handlerID);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Disconnecting handler %lu for signal 'state-changed' at window %p (wnck-window=%p)",
+							handlerID,
+							stageWindow,
+							stageWnckWindow);
+	}
+
+	signalID=g_signal_lookup("active-window-changed", WNCK_TYPE_SCREEN);
+	handlerID=g_signal_handler_find(screen,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_active_window_changed),
+									NULL);
+	if(handlerID)
+	{
+		g_signal_handler_disconnect(screen, handlerID);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Disconnecting handler %lu for signal 'active-window-changed' at screen %p of window %p (wnck-window=%p)",
+							handlerID,
+							screen,
+							stageWindow,
+							stageWnckWindow);
+	}
+
+	signalID=g_signal_lookup("screen-size-changed", XFDASHBOARD_TYPE_WINDOW_TRACKER);
+	handlerID=g_signal_handler_find(priv->windowTracker,
+									G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+									signalID,
+									0,
+									NULL,
+									G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_screen_size_changed),
+									NULL);
+	if(handlerID)
+	{
+		g_signal_handler_disconnect(priv->windowTracker, handlerID);
+		XFDASHBOARD_DEBUG(self, WINDOWS,
+							"Disconnecting handler %lu for signal 'screen-size-changed' at window %p (wnck-window=%p)",
+							handlerID,
+							stageWindow,
+							stageWnckWindow);
+	}
+}
+
+/* Interface initialization
+ * Set up default functions
+ */
+static void _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_iface_init(XfdashboardWindowTrackerBackendInterface *iface)
+{
+	iface->get_name=_xfdashboard_window_tracker_backend_gdk_window_tracker_backend_get_name;
+
+	iface->get_window_tracker=_xfdashboard_window_tracker_backend_gdk_window_tracker_backend_get_window_tracker;
+
+	iface->show_stage_window=_xfdashboard_window_tracker_backend_gdk_window_tracker_backend_show_stage_window;
+	iface->hide_stage_window=_xfdashboard_window_tracker_backend_gdk_window_tracker_backend_hide_stage_window;
+}
+
+
+/* IMPLEMENTATION: GObject */
+
+/* Dispose this object */
+static void _xfdashboard_window_tracker_backend_gdk_dispose(GObject *inObject)
+{
+	XfdashboardWindowTrackerBackendGDK				*self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK(inObject);
+	XfdashboardWindowTrackerBackendGDKPrivate		*priv=self->priv;
+
+	/* Dispose allocated resources */
+	if(priv->windowTracker)
+	{
+		g_object_unref(priv->windowTracker);
+		priv->windowTracker=NULL;
+	}
+
+	/* Call parent's class dispose method */
+	G_OBJECT_CLASS(xfdashboard_window_tracker_backend_gdk_parent_class)->dispose(inObject);
+}
+
+/* Class initialization
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+void xfdashboard_window_tracker_backend_gdk_class_init(XfdashboardWindowTrackerBackendGDKClass *klass)
+{
+	GObjectClass						*gobjectClass=G_OBJECT_CLASS(klass);
+
+	/* Override functions */
+	gobjectClass->dispose=_xfdashboard_window_tracker_backend_gdk_dispose;
+
+	/* Set up private structure */
+	g_type_class_add_private(klass, sizeof(XfdashboardWindowTrackerBackendGDKPrivate));
+}
+
+/* Object initialization
+ * Create private structure and set up default values
+ */
+void xfdashboard_window_tracker_backend_gdk_init(XfdashboardWindowTrackerBackendGDK *self)
+{
+	XfdashboardWindowTrackerBackendGDKPrivate		*priv;
+
+	priv=self->priv=XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK_GET_PRIVATE(self);
+
+	XFDASHBOARD_DEBUG(self, WINDOWS, "Initializing GDK-X11 window tracker backend");
+
+	/* Create window tracker instance */
+	priv->windowTracker=g_object_new(XFDASHBOARD_TYPE_WINDOW_TRACKER_X11, NULL);
+}
diff --git a/libxfdashboard/gdk/window-tracker-backend-gdk.h b/libxfdashboard/gdk/window-tracker-backend-gdk.h
new file mode 100644
index 0000000..77b81f1
--- /dev/null
+++ b/libxfdashboard/gdk/window-tracker-backend-gdk.h
@@ -0,0 +1,74 @@
+/*
+ * window-tracker-backend: Window tracker backend providing special functions
+ *                         for different windowing and clutter backends.
+ * 
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ * 
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifndef __LIBXFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK__
+#define __LIBXFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK__
+
+#if !defined(__LIBXFDASHBOARD_H_INSIDE__) && !defined(LIBXFDASHBOARD_COMPILATION)
+#error "Only <libxfdashboard/libxfdashboard.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+#include <libxfdashboard/window-tracker-backend.h>
+
+G_BEGIN_DECLS
+
+#define XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK				(xfdashboard_window_tracker_backend_gdk_get_type())
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK, XfdashboardWindowTrackerBackendGDK))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK))
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK, XfdashboardWindowTrackerBackendGDKClass))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK))
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK, XfdashboardWindowTrackerBackendGDKClass))
+
+typedef struct _XfdashboardWindowTrackerBackendGDK				XfdashboardWindowTrackerBackendGDK;
+typedef struct _XfdashboardWindowTrackerBackendGDKClass			XfdashboardWindowTrackerBackendGDKClass;
+typedef struct _XfdashboardWindowTrackerBackendGDKPrivate		XfdashboardWindowTrackerBackendGDKPrivate;
+
+struct _XfdashboardWindowTrackerBackendGDK
+{
+	/*< private >*/
+	/* Parent instance */
+	GObject											parent_instance;
+
+	/* Private structure */
+	XfdashboardWindowTrackerBackendGDKPrivate		*priv;
+};
+
+struct _XfdashboardWindowTrackerBackendGDKClass
+{
+	/*< private >*/
+	/* Parent class */
+	GObjectClass									parent_class;
+
+	/*< public >*/
+	/* Virtual functions */
+};
+
+/* Public API */
+GType xfdashboard_window_tracker_backend_gdk_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif	/* __LIBXFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK__ */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list