[Xfce4-commits] <xfce4-panel:master> Make viewports work like workspaces in tasklist (bug #6665).

Nick Schermer noreply at xfce.org
Tue Nov 30 21:50:02 CET 2010


Updating branch refs/heads/master
         to fad961054f9f3554c9f7070c9ee78dacdbecfe74 (commit)
       from 8af236af7d57e8fb4916d2bce9339a29097f6dad (commit)

commit fad961054f9f3554c9f7070c9ee78dacdbecfe74
Author: Nick Schermer <nick at xfce.org>
Date:   Tue Nov 30 21:44:13 2010 +0100

    Make viewports work like workspaces in tasklist (bug #6665).
    
    We will switch to the other viewport with window managers like
    Compiz. We also try to move windows to the current viewport if
    minimized, when this option is enabled.

 plugins/tasklist/tasklist-widget.c |  118 +++++++++++++++++++++++++++++++-----
 1 files changed, 103 insertions(+), 15 deletions(-)

diff --git a/plugins/tasklist/tasklist-widget.c b/plugins/tasklist/tasklist-widget.c
index 92549b1..11a9547 100644
--- a/plugins/tasklist/tasklist-widget.c
+++ b/plugins/tasklist/tasklist-widget.c
@@ -1363,7 +1363,8 @@ xfce_tasklist_active_window_changed (WnckScreen   *screen,
       /* TODO the visible check probably breaks with grouping */
       if (!GTK_WIDGET_VISIBLE (child->button)
           || !(child->window == previous_window
-               || child->window == active_window))
+               || child->window == active_window
+               || !tasklist->all_workspaces))
         continue;
 
       /* update timestamp for window */
@@ -1882,7 +1883,7 @@ xfce_tasklist_wireframe_update (XfceTasklist      *tasklist,
 
   /* get the window geometry */
   wnck_window_get_geometry (child->window, &x, &y, &width, &height);
-
+g_message ("%d %d", x, y);
   gdpy = gtk_widget_get_display (GTK_WIDGET (tasklist));
   dpy = GDK_DISPLAY_XDISPLAY (gdpy);
 
@@ -1961,10 +1962,14 @@ xfce_tasklist_button_visible (XfceTasklistChild *child,
   panel_return_val_if_fail (WNCK_IS_WINDOW (child->window), FALSE);
 
   if (child->tasklist->all_workspaces
-      || (active_ws != NULL ? wnck_window_is_in_viewport (child->window, active_ws)
-           : wnck_window_is_pinned (child->window)))
-    return (!child->tasklist->only_minimized
-            || wnck_window_is_minimized (child->window));
+      || (active_ws != NULL
+          && G_UNLIKELY (wnck_workspace_is_virtual (active_ws))
+             ? wnck_window_is_in_viewport (child->window, active_ws)
+             : wnck_window_is_on_workspace (child->window, active_ws)))
+    {
+      return (!child->tasklist->only_minimized
+              || wnck_window_is_minimized (child->window));
+    }
 
   return FALSE;
 }
@@ -2433,9 +2438,14 @@ xfce_tasklist_button_activate (XfceTasklistChild *child,
                                guint32            timestamp)
 {
   WnckWorkspace *workspace;
+  gint           window_x, window_y;
+  gint           workspace_width, workspace_height;
+  gint           screen_width, screen_height;
+  gint           viewport_x, viewport_y;
 
   panel_return_if_fail (XFCE_IS_TASKLIST (child->tasklist));
   panel_return_if_fail (WNCK_IS_WINDOW (child->window));
+  panel_return_if_fail (WNCK_IS_SCREEN (child->tasklist->screen));
 
   if (wnck_window_is_active (child->window))
     {
@@ -2443,20 +2453,98 @@ xfce_tasklist_button_activate (XfceTasklistChild *child,
     }
   else
     {
-      /* only switch workspaces if we show windows from other
-       * workspaces don't switch when switch on minimize is disabled
-       * and the window is minimized */
+      /* we only change worksapces/viewports for non-pinned windows
+       * and if all workspaces/viewports are shown */
       if (child->tasklist->all_workspaces
-          && (!wnck_window_is_minimized (child->window)
-              || child->tasklist->switch_workspace))
+          && !wnck_window_is_pinned (child->window))
         {
-          /* get the screen of this window and the workspaces */
           workspace = wnck_window_get_workspace (child->window);
 
-          /* switch to the correct workspace */
+          /* only switch workspaces/viewports if switch_workspace is enabled or
+           * we want to restore a minimized window to the current workspace/viewport */
           if (workspace != NULL
-              && workspace != wnck_screen_get_active_workspace (child->tasklist->screen))
-            wnck_workspace_activate (workspace, timestamp - 1);
+              && (child->tasklist->switch_workspace
+                  || !wnck_window_is_minimized (child->window)))
+            {
+              if (G_UNLIKELY (wnck_workspace_is_virtual (workspace)))
+                {
+                  if (!wnck_window_is_in_viewport (child->window, workspace))
+                    {
+                      /* viewport info */
+                      workspace_width = wnck_workspace_get_width (workspace);
+                      workspace_height = wnck_workspace_get_height (workspace);
+                      screen_width = wnck_screen_get_width (child->tasklist->screen);
+                      screen_height = wnck_screen_get_height (child->tasklist->screen);
+
+                      /* we only support multiple viewports like compiz has
+                       * (all equally spread across the screen) */
+                      if ((workspace_width % screen_width) == 0
+                          && (workspace_height % screen_height) == 0)
+                        {
+                          wnck_window_get_geometry (child->window, &window_x, &window_y, NULL, NULL);
+
+                          /* lookup nearest workspace edge */
+                          viewport_x = window_x - (window_x % screen_width);
+                          viewport_x = CLAMP (viewport_x, 0, workspace_width - screen_width);
+
+                          viewport_y = window_y - (window_y % screen_height);
+                          viewport_y = CLAMP (viewport_y, 0, workspace_height - screen_height);
+
+                          /* move to the other viewport */
+                          wnck_screen_move_viewport (child->tasklist->screen, viewport_x, viewport_y);
+                        }
+                      else
+                        {
+                          g_warning ("only viewport with equally distributed screens are supported: %dx%d & %dx%d",
+                                     workspace_width, workspace_height, screen_width, screen_height);
+                        }
+                    }
+                }
+              else if (wnck_screen_get_active_workspace (child->tasklist->screen) != workspace)
+                {
+                  /* switch to the other workspace before we activate the window */
+                  wnck_workspace_activate (workspace, timestamp - 1);
+                }
+            }
+          else if (workspace != NULL
+                   && wnck_workspace_is_virtual (workspace)
+                   && !wnck_window_is_in_viewport (child->window, workspace))
+            {
+              /* viewport info */
+              workspace_width = wnck_workspace_get_width (workspace);
+              workspace_height = wnck_workspace_get_height (workspace);
+              screen_width = wnck_screen_get_width (child->tasklist->screen);
+              screen_height = wnck_screen_get_height (child->tasklist->screen);
+
+              /* we only support multiple viewports like compiz has
+               * (all equaly spread across the screen) */
+              if ((workspace_width % screen_width) == 0
+                  && (workspace_height % screen_height) == 0)
+                {
+                  viewport_x = wnck_workspace_get_viewport_x (workspace);
+                  viewport_y = wnck_workspace_get_viewport_y (workspace);
+
+                  /* note that the x and y might be negative numbers, since they are relative
+                   * to the current screen, not to the edge of the screen they are on. this is
+                   * not a problem since the mod result will always be positive */
+                  wnck_window_get_geometry (child->window, &window_x, &window_y, NULL, NULL);
+
+                  /* get the new screen position, with the same screen offset */
+                  window_x = viewport_x + (window_x % screen_width);
+                  window_y = viewport_y + (window_y % screen_height);
+
+                  /* move the window */
+                  wnck_window_set_geometry (child->window,
+                                            WNCK_WINDOW_GRAVITY_CURRENT,
+                                            WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y,
+                                            window_x, window_y, -1, -1);
+                }
+              else
+                {
+                  g_warning ("only viewport with equally distributed screens are supported: %dx%d & %dx%d",
+                             workspace_width, workspace_height, screen_width, screen_height);
+                }
+            }
         }
 
       wnck_window_activate_transient (child->window, timestamp);



More information about the Xfce4-commits mailing list