[Xfce4-commits] <xfce4-panel:master> Support viewports in pager.

Nick Schermer noreply at xfce.org
Wed Dec 1 21:46:01 CET 2010


Updating branch refs/heads/master
         to 4eb541db81200a78c79a7f9da4ed4451e36d22f7 (commit)
       from 21251bb6df9d12e2ee421305c077900eb3a796dd (commit)

commit 4eb541db81200a78c79a7f9da4ed4451e36d22f7
Author: Nick Schermer <nick at xfce.org>
Date:   Wed Dec 1 21:43:50 2010 +0100

    Support viewports in pager.

 plugins/pager/pager-buttons.c |  228 +++++++++++++++++++++++++++++++++++------
 plugins/pager/pager.c         |   23 +++-
 2 files changed, 212 insertions(+), 39 deletions(-)

diff --git a/plugins/pager/pager-buttons.c b/plugins/pager/pager-buttons.c
index 0e53ebd..08f55df 100644
--- a/plugins/pager/pager-buttons.c
+++ b/plugins/pager/pager-buttons.c
@@ -48,10 +48,14 @@ static void pager_buttons_screen_workspace_created   (WnckScreen    *screen,
 static void pager_buttons_screen_workspace_destroyed (WnckScreen    *screen,
                                                       WnckWorkspace *destroyed_workspace,
                                                       PagerButtons  *pager);
+static void pager_buttons_screen_viewports_changed   (WnckScreen    *screen,
+                                                      PagerButtons  *pager);
 static void pager_buttons_workspace_button_toggled   (GtkWidget     *button,
                                                       WnckWorkspace *workspace);
 static void pager_buttons_workspace_button_label     (WnckWorkspace *workspace,
                                                       GtkWidget     *label);
+static void pager_buttons_viewport_button_toggled    (GtkWidget     *button,
+                                                      PagerButtons  *pager);
 
 
 
@@ -82,6 +86,13 @@ enum
   PROP_ORIENTATION
 };
 
+enum
+{
+  VIEWPORT_X,
+  VIEWPORT_Y,
+  N_INFOS
+};
+
 
 
 XFCE_PANEL_DEFINE_TYPE (PagerButtons, pager_buttons, GTK_TYPE_TABLE)
@@ -187,6 +198,8 @@ pager_buttons_set_property (GObject      *object,
           G_CALLBACK (pager_buttons_screen_workspace_created), pager);
       g_signal_connect (G_OBJECT (pager->wnck_screen), "workspace-destroyed",
           G_CALLBACK (pager_buttons_screen_workspace_destroyed), pager);
+      g_signal_connect (G_OBJECT (pager->wnck_screen), "viewports-changed",
+          G_CALLBACK (pager_buttons_screen_viewports_changed), pager);
 
       pager_buttons_queue_rebuild (pager);
       break;
@@ -223,6 +236,8 @@ pager_buttons_finalize (GObject *object)
           G_CALLBACK (pager_buttons_screen_workspace_created), pager);
       g_signal_handlers_disconnect_by_func (G_OBJECT (pager->wnck_screen),
           G_CALLBACK (pager_buttons_screen_workspace_destroyed), pager);
+      g_signal_handlers_disconnect_by_func (G_OBJECT (pager->wnck_screen),
+          G_CALLBACK (pager_buttons_screen_viewports_changed), pager);
 
       g_object_unref (G_OBJECT (pager->wnck_screen));
     }
@@ -235,6 +250,27 @@ pager_buttons_finalize (GObject *object)
 
 
 static gboolean
+pager_buttons_button_press_event (GtkWidget      *button,
+                                  GdkEventButton *event)
+{
+  guint modifiers;
+
+  panel_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (button), FALSE);
+
+  modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
+
+  /* block toggle events on an active button */
+  if (event->button == 1
+      && modifiers != GDK_CONTROL_MASK
+      && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
+    return TRUE;
+
+  return FALSE;
+}
+
+
+
+static gboolean
 pager_buttons_rebuild_idle (gpointer user_data)
 {
   PagerButtons  *pager = XFCE_PAGER_BUTTONS (user_data);
@@ -247,6 +283,13 @@ pager_buttons_rebuild_idle (gpointer user_data)
   WnckWorkspace *workspace;
   GtkWidget     *panel_plugin;
   GtkWidget     *label;
+  gint           workspace_width, workspace_height;
+  gint           screen_width, screen_height;
+  gint           viewport_x, viewport_y;
+  gboolean       viewport_mode = FALSE;
+  gint           n_viewports;
+  gint          *vp_info;
+  gchar          text[8];
 
   panel_return_val_if_fail (XFCE_IS_PAGER_BUTTONS (pager), FALSE);
   panel_return_val_if_fail (WNCK_IS_SCREEN (pager->wnck_screen), FALSE);
@@ -264,10 +307,43 @@ pager_buttons_rebuild_idle (gpointer user_data)
 
   n_workspaces = g_list_length (workspaces);
 
-  rows = CLAMP (1, pager->rows, n_workspaces);
-  cols = n_workspaces / rows;
-  if (cols * rows < n_workspaces)
-    cols++;
+  /* check if the user uses 1 workspace with viewports */
+  if (G_UNLIKELY (n_workspaces == 1
+      && wnck_workspace_is_virtual (WNCK_WORKSPACE (workspaces->data))))
+    {
+      workspace = WNCK_WORKSPACE (workspaces->data);
+
+      workspace_width = wnck_workspace_get_width (workspace);
+      workspace_height = wnck_workspace_get_height (workspace);
+      screen_width = wnck_screen_get_width (pager->wnck_screen);
+      screen_height = wnck_screen_get_height (pager->wnck_screen);
+
+      /* we only support viewports that are equally spread */
+      if ((workspace_width % screen_width) == 0
+          && (workspace_height % screen_height) == 0)
+        {
+          n_viewports = (workspace_width / screen_width) * (workspace_height / screen_height);
+
+          rows = CLAMP (1, pager->rows, n_viewports);
+          cols = n_workspaces / rows;
+          if (cols * rows < n_workspaces)
+            cols++;
+
+          viewport_mode = TRUE;
+        }
+      else
+        {
+          g_warning ("only viewports with equally distributed screens are supported: %dx%d & %dx%d",
+                     workspace_width, workspace_height, screen_width, screen_height);
+        }
+    }
+  else
+    {
+      rows = CLAMP (1, pager->rows, n_workspaces);
+      cols = n_workspaces / rows;
+      if (cols * rows < n_workspaces)
+        cols++;
+    }
 
   if (pager->orientation != GTK_ORIENTATION_HORIZONTAL)
     SWAP_INTEGER (rows, cols);
@@ -276,36 +352,84 @@ pager_buttons_rebuild_idle (gpointer user_data)
 
   panel_plugin = gtk_widget_get_ancestor (GTK_WIDGET (pager), XFCE_TYPE_PANEL_PLUGIN);
 
-  for (li = workspaces, n = 0; li != NULL; li = li->next, n++)
+  if (G_UNLIKELY (viewport_mode))
+    {
+      panel_return_val_if_fail (WNCK_IS_WORKSPACE (workspace), FALSE);
+
+      viewport_x = wnck_workspace_get_viewport_x (workspace);
+      viewport_y = wnck_workspace_get_viewport_y (workspace);
+
+      for (n = 0; n < n_viewports; n++)
+        {
+          vp_info = g_new0 (gint, N_INFOS);
+          vp_info[VIEWPORT_X] = (n % (workspace_height / screen_height)) * screen_width;
+          vp_info[VIEWPORT_Y] = (n / (workspace_height / screen_height)) * screen_height;
+
+          button = xfce_panel_create_toggle_button ();
+          if (viewport_x >= vp_info[VIEWPORT_X] && viewport_x < vp_info[VIEWPORT_X] + screen_width
+              && viewport_y >= vp_info[VIEWPORT_Y] && viewport_y < vp_info[VIEWPORT_Y] + screen_height)
+            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+          g_signal_connect (G_OBJECT (button), "toggled",
+              G_CALLBACK (pager_buttons_viewport_button_toggled), pager);
+          g_signal_connect (G_OBJECT (button), "button-press-event",
+              G_CALLBACK (pager_buttons_button_press_event), NULL);
+          xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (panel_plugin), button);
+          gtk_widget_show (button);
+
+          g_object_set_data_full (G_OBJECT (button), "viewport-info", vp_info,
+                                  (GDestroyNotify) g_free);
+
+          g_snprintf (text, sizeof (text), "%d", n + 1);
+          label = gtk_label_new (text);
+          gtk_label_set_angle (GTK_LABEL (label),
+              pager->orientation == GTK_ORIENTATION_HORIZONTAL ? 0 : 270);
+          gtk_container_add (GTK_CONTAINER (button), label);
+          gtk_widget_show (label);
+
+          row = n / rows;
+          col = n % rows;
+
+          gtk_table_attach (GTK_TABLE (pager), button,
+                            row, row + 1, col, col + 1,
+                            GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
+                            0, 0);
+        }
+    }
+  else
     {
-      workspace = WNCK_WORKSPACE (li->data);
-
-      button = xfce_panel_create_toggle_button ();
-      if (workspace == active_ws)
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-      g_signal_connect (G_OBJECT (button), "toggled",
-          G_CALLBACK (pager_buttons_workspace_button_toggled), workspace);
-      xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (panel_plugin), button);
-      gtk_widget_show (button);
-
-      label = gtk_label_new (NULL);
-      g_signal_connect_object (G_OBJECT (workspace), "name-changed",
-          G_CALLBACK (pager_buttons_workspace_button_label), label, 0);
-      pager_buttons_workspace_button_label (workspace, label);
-      gtk_label_set_angle (GTK_LABEL (label),
-          pager->orientation == GTK_ORIENTATION_HORIZONTAL ? 0 : 270);
-      gtk_container_add (GTK_CONTAINER (button), label);
-      gtk_widget_show (label);
-
-      pager->buttons = g_slist_prepend (pager->buttons, button);
-
-      row = n / rows;
-      col = n % rows;
-
-      gtk_table_attach (GTK_TABLE (pager), button,
-                        row, row + 1, col, col + 1,
-                        GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
-                        0, 0);
+      for (li = workspaces, n = 0; li != NULL; li = li->next, n++)
+        {
+          workspace = WNCK_WORKSPACE (li->data);
+
+          button = xfce_panel_create_toggle_button ();
+          if (workspace == active_ws)
+            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+          g_signal_connect (G_OBJECT (button), "toggled",
+              G_CALLBACK (pager_buttons_workspace_button_toggled), workspace);
+          g_signal_connect (G_OBJECT (button), "button-press-event",
+              G_CALLBACK (pager_buttons_button_press_event), NULL);
+          xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (panel_plugin), button);
+          gtk_widget_show (button);
+
+          label = gtk_label_new (NULL);
+          g_signal_connect_object (G_OBJECT (workspace), "name-changed",
+              G_CALLBACK (pager_buttons_workspace_button_label), label, 0);
+          pager_buttons_workspace_button_label (workspace, label);
+          gtk_label_set_angle (GTK_LABEL (label),
+              pager->orientation == GTK_ORIENTATION_HORIZONTAL ? 0 : 270);
+          gtk_container_add (GTK_CONTAINER (button), label);
+          gtk_widget_show (label);
+
+          pager->buttons = g_slist_prepend (pager->buttons, button);
+
+          row = n / rows;
+          col = n % rows;
+
+          gtk_table_attach (GTK_TABLE (pager), button,
+                            row, row + 1, col, col + 1,
+                            GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
+                            0, 0);
+        }
     }
 
   pager->buttons = g_slist_reverse (pager->buttons);
@@ -383,7 +507,6 @@ pager_buttons_screen_workspace_destroyed (WnckScreen    *screen,
 {
   panel_return_if_fail (WNCK_IS_SCREEN (screen));
   panel_return_if_fail (WNCK_IS_WORKSPACE (destroyed_workspace));
-  panel_return_if_fail (WNCK_IS_WORKSPACE (destroyed_workspace));
   panel_return_if_fail (XFCE_IS_PAGER_BUTTONS (pager));
   panel_return_if_fail (pager->wnck_screen == screen);
 
@@ -393,6 +516,22 @@ pager_buttons_screen_workspace_destroyed (WnckScreen    *screen,
 
 
 static void
+pager_buttons_screen_viewports_changed (WnckScreen    *screen,
+                                        PagerButtons  *pager)
+{
+  panel_return_if_fail (WNCK_IS_SCREEN (screen));
+  panel_return_if_fail (XFCE_IS_PAGER_BUTTONS (pager));
+  panel_return_if_fail (pager->wnck_screen == screen);
+
+  /* yes we are extremely lazy here, but this event is
+   * also emitted when the viewport setup changes... */
+  if (pager->buttons == NULL)
+    pager_buttons_queue_rebuild (pager);
+}
+
+
+
+static void
 pager_buttons_workspace_button_label (WnckWorkspace *workspace,
                                       GtkWidget     *label)
 {
@@ -439,6 +578,27 @@ pager_buttons_workspace_button_toggled (GtkWidget     *button,
 
 
 
+static void
+pager_buttons_viewport_button_toggled (GtkWidget    *button,
+                                       PagerButtons *pager)
+{
+  gint *vp_info;
+
+  panel_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
+  panel_return_if_fail (XFCE_IS_PAGER_BUTTONS (pager));
+  panel_return_if_fail (WNCK_IS_SCREEN (pager->wnck_screen));
+
+  vp_info = g_object_get_data (G_OBJECT (button), "viewport-info");
+  if (G_UNLIKELY (vp_info == NULL))
+    return;
+
+  wnck_screen_move_viewport (pager->wnck_screen,
+                             vp_info[VIEWPORT_X],
+                             vp_info[VIEWPORT_Y]);
+}
+
+
+
 GtkWidget *
 pager_buttons_new (WnckScreen *screen)
 {
diff --git a/plugins/pager/pager.c b/plugins/pager/pager.c
index 2755b90..3df1286 100644
--- a/plugins/pager/pager.c
+++ b/plugins/pager/pager.c
@@ -438,18 +438,31 @@ pager_plugin_configure_n_workspaces_changed (WnckScreen    *wnck_screen,
                                              WnckWorkspace *workspace,
                                              GtkBuilder    *builder)
 {
-  GObject *object;
-  gdouble  n_worspaces, value;
+  GObject       *object;
+  gdouble        upper, value;
+  WnckWorkspace *active_ws;
 
   panel_return_if_fail (WNCK_IS_SCREEN (wnck_screen));
   panel_return_if_fail (GTK_IS_BUILDER (builder));
 
   object = gtk_builder_get_object (builder, "rows");
 
-  n_worspaces = wnck_screen_get_workspace_count (wnck_screen);
-  value = MIN (gtk_adjustment_get_value (GTK_ADJUSTMENT (object)), n_worspaces);
+  upper = wnck_screen_get_workspace_count (wnck_screen);
+  if (upper == 1)
+    {
+      /* check if we ware in viewport mode */
+      active_ws = wnck_screen_get_active_workspace (wnck_screen);
+      if (wnck_workspace_is_virtual (active_ws))
+        {
+          /* number of rows * number of columns */
+          upper = (wnck_workspace_get_width (active_ws) / wnck_screen_get_width (wnck_screen))
+                  * (wnck_workspace_get_height (active_ws) / wnck_screen_get_height (wnck_screen));
+        }
+    }
+
+  value = MIN (gtk_adjustment_get_value (GTK_ADJUSTMENT (object)), upper);
 
-  g_object_set (G_OBJECT (object), "upper", n_worspaces, "value", value, NULL);
+  g_object_set (G_OBJECT (object), "upper", upper, "value", value, NULL);
 }
 
 



More information about the Xfce4-commits mailing list