[Xfce4-commits] [apps/xfdashboard] 01/01: Implement signal to notify if a window has moved to another monitor

noreply at xfce.org noreply at xfce.org
Fri May 1 14:33:43 CEST 2015


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

nomad pushed a commit to branch master
in repository apps/xfdashboard.

commit 5da4858dd005446c50b8fd2c45a1584b1eb6a049
Author: Stephan Haller <nomad at froevel.de>
Date:   Fri May 1 14:29:01 2015 +0200

    Implement signal to notify if a window has moved to another monitor
    
    Implement a new signal 'window-monitor-changed' at window tracker to signal that a window has moved from one monitor to another. This is done by tracking the last position and size to determine the old monitor where this window was placed. If the new position and size of this window is at another monitor this new signal is emitted.
    
    This signal is used by the windows view to determine if the moved window has to stay in this view or if another window view instance has to create an actor for this window and to handle it.
    
    This new signal is only useful in multi-monitor setups.
    
    This commit addresses issue GH #88
---
 xfdashboard/window-tracker.c |  107 +++++++++++++++++++++++++++++++++++++++++-
 xfdashboard/window-tracker.h |    4 ++
 xfdashboard/windows-view.c   |   80 +++++++++++++++++++++++++++++--
 3 files changed, 185 insertions(+), 6 deletions(-)

diff --git a/xfdashboard/window-tracker.c b/xfdashboard/window-tracker.c
index 185df16..e4820c7 100644
--- a/xfdashboard/window-tracker.c
+++ b/xfdashboard/window-tracker.c
@@ -99,6 +99,7 @@ enum
 	SIGNAL_WINDOW_ICON_CHANGED,
 	SIGNAL_WINDOW_NAME_CHANGED,
 	SIGNAL_WINDOW_WORKSPACE_CHANGED,
+	SIGNAL_WINDOW_MONITOR_CHANGED,
 
 	SIGNAL_ACTIVE_WORKSPACE_CHANGED,
 	SIGNAL_WORKSPACE_ADDED,
@@ -117,22 +118,103 @@ enum
 static guint XfdashboardWindowTrackerSignals[SIGNAL_LAST]={ 0, };
 
 /* IMPLEMENTATION: Private variables and methods */
+#define LAST_X_DATA_KEY			"last-x"
+#define LAST_Y_DATA_KEY			"last-y"
+#define LAST_WIDTH_DATA_KEY		"last-width"
+#define LAST_HEIGHT_DATA_KEY	"last-height"
+
 static XfdashboardWindowTracker *_xfdashboard_window_tracker_singleton=NULL;
 
 
 /* Position and/or size of window has changed */
 static void _xfdashboard_window_tracker_on_window_geometry_changed(XfdashboardWindowTracker *self, gpointer inUserData)
 {
-	WnckWindow			*window;
+	XfdashboardWindowTrackerPrivate			*priv;
+	WnckWindow								*window;
+	gint									x, y, width, height;
+	gint									lastX, lastY, lastWidth, lastHeight;
+	XfdashboardWindowTrackerMonitor			*currentMonitor;
+	XfdashboardWindowTrackerMonitor			*lastMonitor;
+	GList									*iter;
+	gint									screenWidth, screenHeight;
+	gint									windowMiddleX, windowMiddleY;
 
 	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
 	g_return_if_fail(WNCK_IS_WINDOW(inUserData));
 
+	priv=self->priv;
 	window=WNCK_WINDOW(inUserData);
 
+	/* Get last and current position and size of window to determine
+	 * if window has moved or resized and do not emit this signal if
+	 * neither happened, although it is very unlike that the window
+	 * has not moved or resized if this signal was called.
+	 */
+	lastX=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(window), LAST_X_DATA_KEY));
+	lastY=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(window), LAST_Y_DATA_KEY));
+	lastWidth=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(window), LAST_WIDTH_DATA_KEY));
+	lastHeight=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(window), LAST_HEIGHT_DATA_KEY));
+
+	xfdashboard_window_tracker_window_get_position_size(window, &x, &y, &width, &height);
+
+	if(G_UNLIKELY(lastX==x && lastY==y && lastWidth==width && lastHeight==height))
+	{
+		g_debug("Window '%s' has not moved or resized", wnck_window_get_name(window));
+		return;
+	}
+
 	/* Emit signal */
 	g_debug("Window '%s' changed position and/or size", wnck_window_get_name(window));
 	g_signal_emit(self, XfdashboardWindowTrackerSignals[SIGNAL_WINDOW_GEOMETRY_CHANGED], 0, window);
+
+	/* Get monitor at old position of window and the monitor at current position.
+	 * If they differ emit signal for window changed monitor.
+	 */
+	screenWidth=xfdashboard_window_tracker_get_screen_width(self);
+	screenHeight=xfdashboard_window_tracker_get_screen_height(self);
+
+	windowMiddleX=lastX+(lastWidth/2);
+	if(windowMiddleX>screenWidth) windowMiddleX=screenWidth-1;
+
+	windowMiddleY=lastY+(lastHeight/2);
+	if(windowMiddleY>screenHeight) windowMiddleY=screenHeight-1;
+
+	lastMonitor=NULL;
+	for(iter=priv->monitors; iter && !lastMonitor; iter=g_list_next(iter))
+	{
+		gint								monitorX, monitorY, monitorWidth, monitorHeight;
+		XfdashboardWindowTrackerMonitor		*monitor;
+
+		/* Get monitor */
+		monitor=XFDASHBOARD_WINDOW_TRACKER_MONITOR(iter->data);
+
+		/* Get monitor geometry */
+		xfdashboard_window_tracker_monitor_get_geometry(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight);
+
+		/* Check if mid-point of window (adjusted to screen size) is within monitor */
+		if(windowMiddleX>=monitorX && windowMiddleX<(monitorX+monitorWidth) &&
+			windowMiddleY>=monitorY && windowMiddleY<(monitorY+monitorHeight))
+		{
+			lastMonitor=monitor;
+		}
+	}
+
+	currentMonitor=xfdashboard_window_tracker_window_get_monitor(window);
+	if(currentMonitor!=lastMonitor)
+	{
+		/* Emit signal */
+		g_debug("Window '%s' moved from monitor %d to %d",
+					wnck_window_get_name(window),
+					xfdashboard_window_tracker_monitor_get_number(lastMonitor),
+					xfdashboard_window_tracker_monitor_get_number(currentMonitor));
+		g_signal_emit(self, XfdashboardWindowTrackerSignals[SIGNAL_WINDOW_MONITOR_CHANGED], 0, window, lastMonitor, currentMonitor);
+	}
+
+	/* Remember new position and size as last known ones */
+	g_object_set_data(G_OBJECT(window), LAST_X_DATA_KEY, GINT_TO_POINTER(x));
+	g_object_set_data(G_OBJECT(window), LAST_Y_DATA_KEY, GINT_TO_POINTER(y));
+	g_object_set_data(G_OBJECT(window), LAST_WIDTH_DATA_KEY, GINT_TO_POINTER(width));
+	g_object_set_data(G_OBJECT(window), LAST_HEIGHT_DATA_KEY, GINT_TO_POINTER(height));
 }
 
 /* Action items of window has changed */
@@ -281,10 +363,19 @@ static void _xfdashboard_window_tracker_on_window_opened(XfdashboardWindowTracke
 															WnckWindow *inWindow,
 															gpointer inUserData)
 {
+	gint		x, y, width, height;
+
 	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(self));
 	g_return_if_fail(WNCK_IS_WINDOW(inWindow));
 	g_return_if_fail(WNCK_IS_SCREEN(inUserData));
 
+	/* Remember current position and size as last known ones */
+	xfdashboard_window_tracker_window_get_position_size(inWindow, &x, &y, &width, &height);
+	g_object_set_data(G_OBJECT(inWindow), LAST_X_DATA_KEY, GINT_TO_POINTER(x));
+	g_object_set_data(G_OBJECT(inWindow), LAST_Y_DATA_KEY, GINT_TO_POINTER(y));
+	g_object_set_data(G_OBJECT(inWindow), LAST_WIDTH_DATA_KEY, GINT_TO_POINTER(width));
+	g_object_set_data(G_OBJECT(inWindow), LAST_HEIGHT_DATA_KEY, GINT_TO_POINTER(height));
+
 	/* Connect signals on newly opened window */
 	g_signal_connect_swapped(inWindow, "geometry-changed", G_CALLBACK(_xfdashboard_window_tracker_on_window_geometry_changed), self);
 	g_signal_connect_swapped(inWindow, "actions-changed", G_CALLBACK(_xfdashboard_window_tracker_on_window_actions_changed), self);
@@ -878,6 +969,20 @@ void xfdashboard_window_tracker_class_init(XfdashboardWindowTrackerClass *klass)
 						WNCK_TYPE_WINDOW,
 						WNCK_TYPE_WORKSPACE);
 
+	XfdashboardWindowTrackerSignals[SIGNAL_WINDOW_MONITOR_CHANGED]=
+		g_signal_new("window-monitor-changed",
+						G_TYPE_FROM_CLASS(klass),
+						G_SIGNAL_RUN_LAST,
+						G_STRUCT_OFFSET(XfdashboardWindowTrackerClass, window_monitor_changed),
+						NULL,
+						NULL,
+						_xfdashboard_marshal_VOID__OBJECT_OBJECT_OBJECT,
+						G_TYPE_NONE,
+						3,
+						WNCK_TYPE_WINDOW,
+						XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR,
+						XFDASHBOARD_TYPE_WINDOW_TRACKER_MONITOR);
+
 	XfdashboardWindowTrackerSignals[SIGNAL_ACTIVE_WORKSPACE_CHANGED]=
 		g_signal_new("active-workspace-changed",
 						G_TYPE_FROM_CLASS(klass),
diff --git a/xfdashboard/window-tracker.h b/xfdashboard/window-tracker.h
index 587e3f4..7e68c4d 100644
--- a/xfdashboard/window-tracker.h
+++ b/xfdashboard/window-tracker.h
@@ -81,6 +81,10 @@ struct _XfdashboardWindowTrackerClass
 	void (*window_workspace_changed)(XfdashboardWindowTracker *self,
 										XfdashboardWindowTrackerWindow *inWindow,
 										XfdashboardWindowTrackerWorkspace *inWorkspace);
+	void (*window_monitor_changed)(XfdashboardWindowTracker *self,
+										XfdashboardWindowTrackerWindow *inWindow,
+										XfdashboardWindowTrackerMonitor *inOldMonitor,
+										XfdashboardWindowTrackerMonitor *inNewMonitor);
 
 	void (*active_workspace_changed)(XfdashboardWindowTracker *self,
 										XfdashboardWindowTrackerWorkspace *inOldWorkspace,
diff --git a/xfdashboard/windows-view.c b/xfdashboard/windows-view.c
index 4feaafe..bcc518a 100644
--- a/xfdashboard/windows-view.c
+++ b/xfdashboard/windows-view.c
@@ -450,12 +450,16 @@ static void _xfdashboard_windows_view_on_window_opened(XfdashboardWindowsView *s
 		/* Check if window is visible on this workspace */
 		if(!_xfdashboard_windows_view_is_visible_window(self, inWindow)) return;
 
-		/* Create actor */
-		liveWindow=_xfdashboard_windows_view_create_actor(self, inWindow);
-		if(liveWindow)
+		/* Create actor if it does not exist already */
+		liveWindow=_xfdashboard_windows_view_find_by_window(self, inWindow);
+		if(G_LIKELY(!liveWindow))
 		{
-			clutter_actor_insert_child_below(CLUTTER_ACTOR(self), CLUTTER_ACTOR(liveWindow), NULL);
-			_xfdashboard_windows_view_update_window_number_in_actors(self);
+			liveWindow=_xfdashboard_windows_view_create_actor(self, inWindow);
+			if(liveWindow)
+			{
+				clutter_actor_insert_child_below(CLUTTER_ACTOR(self), CLUTTER_ACTOR(liveWindow), NULL);
+				_xfdashboard_windows_view_update_window_number_in_actors(self);
+			}
 		}
 	}
 		else
@@ -496,6 +500,67 @@ static void _xfdashboard_windows_view_on_window_closed(XfdashboardWindowsView *s
 		}
 }
 
+/* A window has changed monitor */
+static void _xfdashboard_windows_view_on_window_monitor_changed(XfdashboardWindowsView *self,
+																XfdashboardWindowTrackerWindow *inWindow,
+																XfdashboardWindowTrackerMonitor *inOldMonitor,
+																XfdashboardWindowTrackerMonitor *inNewMonitor,
+																gpointer inUserData)
+{
+	XfdashboardWindowsViewPrivate		*priv;
+	XfdashboardLiveWindow				*liveWindow;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOWS_VIEW(self));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR(inOldMonitor));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_MONITOR(inNewMonitor));
+
+	priv=self->priv;
+
+	/* Check if parent stage interface changed. If not check if window has
+	 * moved away from this view and destroy it or it has moved to this view
+	 * and create it. Otherwise recreate all window actors for changed stage
+	 * interface and monitor.
+	 */
+	if(!_xfdashboard_windows_view_update_stage_and_monitor(self))
+	{
+		/* Check if window moved away from this view*/
+		if(priv->currentMonitor==inOldMonitor &&
+			!_xfdashboard_windows_view_is_visible_window(self, inWindow))
+		{
+			/* Find live window for window to destroy it */
+			liveWindow=_xfdashboard_windows_view_find_by_window(self, inWindow);
+			if(G_LIKELY(liveWindow))
+			{
+				/* Destroy actor */
+				clutter_actor_destroy(CLUTTER_ACTOR(liveWindow));
+			}
+		}
+
+		/* Check if window moved to this view */
+		if(priv->currentMonitor==inNewMonitor &&
+			_xfdashboard_windows_view_is_visible_window(self, inWindow))
+		{
+			/* Create actor if it does not exist already */
+			liveWindow=_xfdashboard_windows_view_find_by_window(self, inWindow);
+			if(G_LIKELY(!liveWindow))
+			{
+				liveWindow=_xfdashboard_windows_view_create_actor(self, inWindow);
+				if(liveWindow)
+				{
+					clutter_actor_insert_child_below(CLUTTER_ACTOR(self), CLUTTER_ACTOR(liveWindow), NULL);
+					_xfdashboard_windows_view_update_window_number_in_actors(self);
+				}
+			}
+		}
+	}
+		else
+		{
+			/* Recreate all window actors because parent stage interface changed */
+			_xfdashboard_windows_view_recreate_window_actors(self);
+		}
+}
+
 /* A live window was clicked */
 static void _xfdashboard_windows_view_on_window_clicked(XfdashboardWindowsView *self,
 														gpointer inUserData)
@@ -1879,6 +1944,11 @@ static void xfdashboard_windows_view_init(XfdashboardWindowsView *self)
 								G_CALLBACK(_xfdashboard_windows_view_on_window_closed),
 								self);
 
+	g_signal_connect_swapped(priv->windowTracker,
+								"window-monitor-changed",
+								G_CALLBACK(_xfdashboard_windows_view_on_window_monitor_changed),
+								self);
+
 	/* If active workspace is already available then set up this view */
 	activeWorkspace=xfdashboard_window_tracker_get_active_workspace(priv->windowTracker);
 	if(activeWorkspace)

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


More information about the Xfce4-commits mailing list