[Xfce4-commits] <xfwm4:ochosi/tabwin> Implement column list overflow tabwin mode

Simon Steinbeiss noreply at xfce.org
Sat Nov 30 22:08:02 CET 2013


Updating branch refs/heads/ochosi/tabwin
         to 142904be056f9d469726848c61d8ff33e97fae4c (commit)
       from 465cc5b73af615fe7a3ba7067637b7f32bb0fb6d (commit)

commit 142904be056f9d469726848c61d8ff33e97fae4c
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Sat Nov 30 23:37:07 2013 +0300

    Implement column list overflow tabwin mode
    
    Adds an list view for the tabwin when cycling windows, as described
    in the design SIG. An xfconf property and option to the wm tweaks
    app has been added.
    
    Signed-off-by: Simon Steinbeiss <simon.steinbeiss at elfenbeinturm.at>

 defaults/defaults                          |    1 +
 settings-dialogs/tweaks-settings.c         |    5 +
 settings-dialogs/xfwm4-tweaks-dialog.glade |   16 ++
 src/settings.c                             |    7 +
 src/settings.h                             |    1 +
 src/tabwin.c                               |  252 +++++++++++++++++++++++-----
 src/tabwin.h                               |    7 +
 7 files changed, 247 insertions(+), 42 deletions(-)

diff --git a/defaults/defaults b/defaults/defaults
index 17dc3d7..78c15a5 100644
--- a/defaults/defaults
+++ b/defaults/defaults
@@ -10,6 +10,7 @@ cycle_draw_frame=true
 cycle_apps_only=false
 cycle_hidden=true
 cycle_minimum=true
+cycle_tabwin_mode=0
 cycle_workspaces=false
 double_click_time=250
 double_click_distance=5
diff --git a/settings-dialogs/tweaks-settings.c b/settings-dialogs/tweaks-settings.c
index 0b6a7eb..8990f07 100644
--- a/settings-dialogs/tweaks-settings.c
+++ b/settings-dialogs/tweaks-settings.c
@@ -167,6 +167,7 @@ wm_tweaks_dialog_configure_widgets (GtkBuilder *builder)
     GtkWidget *cycle_hidden_check = GTK_WIDGET (gtk_builder_get_object (builder, "cycle_hidden_check"));
     GtkWidget *cycle_minimum_check = GTK_WIDGET (gtk_builder_get_object (builder, "cycle_minimum_check"));
     GtkWidget *cycle_draw_frame = GTK_WIDGET (gtk_builder_get_object (builder, "cycle_draw_frame"));
+    GtkWidget *cycle_tabwin_mode = GTK_WIDGET (gtk_builder_get_object (builder, "cycle_tabwin_mode"));
 
     /* Focus tab */
     GtkWidget *prevent_focus_stealing_check = GTK_WIDGET (gtk_builder_get_object (builder, "prevent_focus_stealing_check"));
@@ -316,6 +317,10 @@ wm_tweaks_dialog_configure_widgets (GtkBuilder *builder)
                             "/general/cycle_draw_frame",
                             G_TYPE_BOOLEAN,
                             (GObject *)cycle_draw_frame, "active");
+    xfconf_g_property_bind (xfwm4_channel,
+                            "/general/cycle_tabwin_mode",
+                            G_TYPE_INT,
+                            (GObject *)cycle_tabwin_mode, "active");
 
     /* Focus tab */
     xfconf_g_property_bind (xfwm4_channel,
diff --git a/settings-dialogs/xfwm4-tweaks-dialog.glade b/settings-dialogs/xfwm4-tweaks-dialog.glade
index d026dfd..7f12809 100644
--- a/settings-dialogs/xfwm4-tweaks-dialog.glade
+++ b/settings-dialogs/xfwm4-tweaks-dialog.glade
@@ -171,6 +171,22 @@ or "skip taskbar" properties set</property>
                     <property name="position">3</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkCheckButton" id="cycle_tabwin_mode">
+                    <property name="label" translatable="yes">Show windows being cycled in a _list instead of an icon grid</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">4</property>
+                  </packing>
+                </child>
               </object>
             </child>
             <child type="tab">
diff --git a/src/settings.c b/src/settings.c
index a8a9e06..bfa8af3 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -678,6 +678,7 @@ loadSettings (ScreenInfo *screen_info)
         {"cycle_draw_frame", NULL, G_TYPE_BOOLEAN, TRUE},
         {"cycle_hidden", NULL, G_TYPE_BOOLEAN, TRUE},
         {"cycle_minimum", NULL, G_TYPE_BOOLEAN, TRUE},
+        {"cycle_tabwin_mode", NULL, G_TYPE_INT, FALSE},
         {"cycle_workspaces", NULL, G_TYPE_BOOLEAN, TRUE},
         {"double_click_time", NULL, G_TYPE_INT, TRUE},
         {"double_click_distance", NULL, G_TYPE_INT, TRUE},
@@ -768,6 +769,8 @@ loadSettings (ScreenInfo *screen_info)
         getBoolValue ("cycle_draw_frame", rc);
     screen_info->params->cycle_hidden =
         getBoolValue ("cycle_hidden", rc);
+    screen_info->params->cycle_tabwin_mode =
+        CLAMP (getIntValue ("cycle_tabwin_mode", rc), 0, 1);
     screen_info->params->cycle_workspaces =
         getBoolValue ("cycle_workspaces", rc);
     screen_info->params->focus_hint =
@@ -1186,6 +1189,10 @@ cb_xfwm4_channel_property_changed(XfconfChannel *channel, const gchar *property_
                 {
                     screen_info->params->placement_ratio = CLAMP (g_value_get_int(value), 0, 100);
                 }
+                else if (!strcmp (name, "cycle_tabwin_mode"))
+                {
+                    screen_info->params->cycle_tabwin_mode = CLAMP (g_value_get_int(value), 0, 1);
+                }
                 else if ((!strcmp (name, "button_offset"))
                       || (!strcmp (name, "button_spacing"))
                       || (!strcmp (name, "double_click_time"))
diff --git a/src/settings.h b/src/settings.h
index d595ddc..a5038c8 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -174,6 +174,7 @@ struct _XfwmParams
     int activate_action;
     int button_offset;
     int button_spacing;
+    int cycle_tabwin_mode;
     int double_click_action;
     guint easy_click;
     int focus_delay;
diff --git a/src/tabwin.c b/src/tabwin.c
index 72f79d2..c25a403 100644
--- a/src/tabwin.c
+++ b/src/tabwin.c
@@ -55,6 +55,7 @@
 #include "icons.h"
 #include "focus.h"
 #include "tabwin.h"
+#include "settings.h"
 
 static void tabwin_widget_class_init (TabwinWidgetClass *klass);
 
@@ -118,7 +119,7 @@ tabwin_expose (GtkWidget *tbw, GdkEventExpose *event, gpointer data)
     gdouble border_alpha = WIN_BORDER_ALPHA;
     gdouble alpha = WIN_ALPHA;
     gint border_radius = WIN_BORDER_RADIUS;
-    gdouble degrees = 3.14 / 180.0;
+    gdouble degrees = G_PI / 180.0;
     gdouble width = tbw->allocation.width;
     gdouble height = tbw->allocation.height;
 
@@ -135,7 +136,8 @@ tabwin_expose (GtkWidget *tbw, GdkEventExpose *event, gpointer data)
                             NULL);
     cairo_set_line_width (cr, border_width);
     
-    if (gdk_screen_is_composited(screen)) {
+    if (gdk_screen_is_composited (screen))
+    {
         cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
         gdk_cairo_region(cr, event->region);
         cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0);
@@ -154,7 +156,8 @@ tabwin_expose (GtkWidget *tbw, GdkEventExpose *event, gpointer data)
         cairo_set_source_rgba (cr, bg_selected->red/65535.0, bg_selected->green/65535.0, bg_selected->blue/65535.0, border_alpha);
         cairo_stroke (cr);
     }
-    else{
+    else
+    {
         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
         cairo_rectangle(cr, 0, 0, width, height);
         gdk_cairo_set_source_color(cr, bg_normal);
@@ -248,10 +251,17 @@ tabwinSetSelected (TabwinWidget *tbw, GtkWidget *w, GtkWidget *l)
                                                "expose-event",
                                                G_CALLBACK (paint_selected),
                                                NULL);
+
     c = g_object_get_data (G_OBJECT (tbw->selected), "client-ptr-val");
 
     if (c != NULL)
     {
+        /* We don't update labels here */
+        if (c->screen_info->params->cycle_tabwin_mode == OVERFLOW_COLUMN_GRID)
+        {
+            return;
+        }
+
         classname = g_strdup(c->class.res_class);
         tabwinSetLabel (tbw, l, classname, c->name, c->win_workspace);
         g_free (classname);
@@ -309,6 +319,20 @@ getMinMonitorWidth (ScreenInfo *screen_info)
     return min_width;
 }
 
+static int
+getMinMonitorHeight (ScreenInfo *screen_info)
+{
+    int i, min_height, num_monitors = myScreenGetNumMonitors (screen_info);
+    for (min_height = i = 0; i < num_monitors; i++)
+    {
+        GdkRectangle monitor;
+        gdk_screen_get_monitor_geometry (screen_info->gscr, i, &monitor);
+        if (min_height == 0 || monitor.height < min_height)
+            min_height = monitor.height;
+    }
+    return min_height;
+}
+
 static gboolean
 cb_window_button_enter (GtkWidget *widget, GdkEvent *event, gpointer user_data)
 {
@@ -321,15 +345,21 @@ cb_window_button_enter (GtkWidget *widget, GdkEvent *event, gpointer user_data)
 
     g_return_val_if_fail (tbw != NULL, FALSE);
 
-    c = g_object_get_data (G_OBJECT (widget), "client-ptr-val");
-
     /* keep track of which widget we're hovered over */
     tbw->tabwin->hovered = widget;
 
+    c = g_object_get_data (G_OBJECT (widget), "client-ptr-val");
+
     /* when hovering over a window icon, display it's label but don't
      * select it */
     if (c != NULL)
     {
+        /* we don't update the labels on mouse over for this mode */
+        if (c->screen_info->params->cycle_tabwin_mode == OVERFLOW_COLUMN_GRID)
+        {
+            return FALSE;
+        }
+
         buttonbox = GTK_WIDGET( gtk_container_get_children(GTK_CONTAINER(widget))[0].data );
         buttonlabel = GTK_WIDGET( g_list_nth_data( gtk_container_get_children(GTK_CONTAINER(buttonbox)), 1) );
 
@@ -345,6 +375,7 @@ static gboolean
 cb_window_button_leave (GtkWidget *widget, GdkEvent *event, gpointer user_data)
 {
     TabwinWidget *tbw = user_data;
+    Client *c;
 
     TRACE ("entering");
 
@@ -358,8 +389,21 @@ cb_window_button_leave (GtkWidget *widget, GdkEvent *event, gpointer user_data)
 
     tbw->tabwin->hovered = NULL;
 
-    /* reselect the selected widget, it will clear everything else out */
-    tabwinSelectWidget (tbw->tabwin);
+    c = g_object_get_data (G_OBJECT (widget), "client-ptr-val");
+
+    /* when hovering over a window icon, display it's label but don't
+     * select it */
+    if (c != NULL)
+    {
+        /* we don't update the labels for this mode */
+        if (c->screen_info->params->cycle_tabwin_mode == OVERFLOW_COLUMN_GRID)
+        {
+            return FALSE;
+        }
+
+        /* reselect the selected widget, it will clear everything else out */
+        tabwinSelectWidget (tbw->tabwin);
+    }
 
     return FALSE;
 }
@@ -370,7 +414,7 @@ createWindowlist (ScreenInfo *screen_info, TabwinWidget *tbw)
     Client *c;
     GList *client_list;
     GtkWidget *windowlist, *icon, *selected, *window_button, *buttonbox, *buttonlabel, *selected_label;
-    int packpos, monitor_width;
+    int packpos, monitor_width, monitor_height;
     Tabwin *t;
     gint icon_size = WIN_ICON_SIZE;
 
@@ -381,13 +425,26 @@ createWindowlist (ScreenInfo *screen_info, TabwinWidget *tbw)
     selected = NULL;
     t = tbw->tabwin;
     monitor_width = getMinMonitorWidth (screen_info);
+    monitor_height = getMinMonitorHeight (screen_info);
     g_return_val_if_fail (screen_info->client_count > 0, NULL);
 
     gtk_widget_style_get (GTK_WIDGET (tbw), "icon-size", &icon_size, NULL);
-    tbw->grid_cols = (monitor_width / (icon_size + 2 * WIN_ICON_BORDER)) * 0.75;
-    tbw->grid_rows = screen_info->client_count / tbw->grid_cols + 1;
     tbw->widgets = NULL;
+
+    if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+    {
+        tbw->grid_cols = (monitor_width / (icon_size + 2 * WIN_ICON_BORDER)) * 0.75;
+        tbw->grid_rows = screen_info->client_count / tbw->grid_cols + 1;
+    }
+    else
+    {
+        icon_size = 24;
+        tbw->grid_rows = (monitor_height / (icon_size + 2 * WIN_ICON_BORDER)) * 0.75;
+        tbw->grid_cols = screen_info->client_count / tbw->grid_rows + 1;
+    }
+
     windowlist = gtk_table_new (tbw->grid_rows, tbw->grid_cols, FALSE);
+
     /* pack the client icons */
     for (client_list = *t->client_list; client_list; client_list = g_list_next (client_list))
     {
@@ -396,28 +453,50 @@ createWindowlist (ScreenInfo *screen_info, TabwinWidget *tbw)
 
         window_button = gtk_button_new ();
         gtk_button_set_relief (GTK_BUTTON (window_button), GTK_RELIEF_NONE);
-        gtk_widget_set_size_request (GTK_WIDGET (window_button), icon_size+24, icon_size+24);
         g_object_set_data (G_OBJECT (window_button), "client-ptr-val", c);
         g_signal_connect (window_button, "enter-notify-event", G_CALLBACK (cb_window_button_enter), tbw);
         g_signal_connect (window_button, "leave-notify-event", G_CALLBACK (cb_window_button_leave), tbw);
         gtk_widget_add_events (window_button, GDK_ENTER_NOTIFY_MASK);
 
-        buttonbox = gtk_vbox_new (FALSE, 0);
+        if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+        {
+            gtk_widget_set_size_request (GTK_WIDGET (window_button), icon_size+24, icon_size+24);
+            buttonbox = gtk_vbox_new (FALSE, 0);
+            buttonlabel = gtk_label_new ("");
+            gtk_misc_set_alignment (GTK_MISC (buttonlabel), 0.5, 1.0);
+        }
+        else
+        {
+            gtk_widget_set_size_request (GTK_WIDGET (window_button), icon_size+256, icon_size+8);
+            buttonbox = gtk_hbox_new (FALSE, 6);
+            buttonlabel = gtk_label_new (c->name);
+            gtk_misc_set_alignment (GTK_MISC (buttonlabel), 0, 0.5);
+        }
+
         gtk_container_add (GTK_CONTAINER (window_button), buttonbox);
         
         icon = createWindowIcon (c, icon_size);
         gtk_box_pack_start (GTK_BOX (buttonbox), icon, FALSE, TRUE, 0);
-        
-        buttonlabel = gtk_label_new ("");
-        gtk_misc_set_alignment (GTK_MISC (buttonlabel), 0.5, 1.0);
+
         gtk_label_set_justify (GTK_LABEL (buttonlabel), GTK_JUSTIFY_CENTER);
         gtk_label_set_ellipsize (GTK_LABEL (buttonlabel), PANGO_ELLIPSIZE_END);
         gtk_box_pack_start (GTK_BOX (buttonbox), buttonlabel, TRUE, TRUE, 0);
 
-        gtk_table_attach (GTK_TABLE (windowlist), GTK_WIDGET (window_button),
-            packpos % tbw->grid_cols, packpos % tbw->grid_cols + 1,
-            packpos / tbw->grid_cols, packpos / tbw->grid_cols + 1,
-            GTK_FILL, GTK_FILL, 2, 2);
+        if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+        {
+            gtk_table_attach (GTK_TABLE (windowlist), GTK_WIDGET (window_button),
+                packpos % tbw->grid_cols, packpos % tbw->grid_cols + 1,
+                packpos / tbw->grid_cols, packpos / tbw->grid_cols + 1,
+                GTK_FILL, GTK_FILL, 2, 2);
+        }
+        else
+        {
+            gtk_table_attach (GTK_TABLE (windowlist), GTK_WIDGET (window_button),
+                packpos / tbw->grid_rows, packpos / tbw->grid_rows + 1,
+                packpos % tbw->grid_rows, packpos % tbw->grid_rows + 1,
+                GTK_FILL, GTK_FILL, 2, 2);
+        }
+
         tbw->widgets = g_list_append (tbw->widgets, window_button);
         packpos++;
         if (c == t->selected->data)
@@ -549,11 +628,14 @@ tabwinCreateWidget (Tabwin *tabwin, ScreenInfo *screen_info, gint monitor_num)
     vbox = gtk_vbox_new (FALSE, 3);
     gtk_container_add (GTK_CONTAINER (tbw), vbox);
 
-    tbw->label = gtk_label_new ("");
-    gtk_label_set_use_markup (GTK_LABEL (tbw->label), TRUE);
-    gtk_label_set_justify (GTK_LABEL (tbw->label), GTK_JUSTIFY_CENTER);
-    gtk_label_set_ellipsize (GTK_LABEL (tbw->label), PANGO_ELLIPSIZE_END);
-    gtk_box_pack_end (GTK_BOX (vbox), tbw->label, TRUE, TRUE, 0);
+    if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+    {
+        tbw->label = gtk_label_new ("");
+        gtk_label_set_use_markup (GTK_LABEL (tbw->label), TRUE);
+        gtk_label_set_justify (GTK_LABEL (tbw->label), GTK_JUSTIFY_CENTER);
+        gtk_label_set_ellipsize (GTK_LABEL (tbw->label), PANGO_ELLIPSIZE_END);
+        gtk_box_pack_end (GTK_BOX (vbox), tbw->label, TRUE, TRUE, 0);
+    }
 
     windowlist = createWindowlist (screen_info, tbw);
     tbw->container = windowlist;
@@ -574,6 +656,7 @@ tabwinChange2Selected (Tabwin *t, GList *selected)
     GList *tabwin_list, *widgets;
     GtkWidget *window_button, *buttonbox, *buttonlabel;
     TabwinWidget *tbw;
+    Client *c;
 
     t->selected = selected;
     for (tabwin_list = t->tabwin_list; tabwin_list; tabwin_list = g_list_next (tabwin_list))
@@ -585,12 +668,21 @@ tabwinChange2Selected (Tabwin *t, GList *selected)
             gtk_button_set_relief (GTK_BUTTON (window_button), GTK_RELIEF_NONE);
             buttonbox = GTK_WIDGET( gtk_container_get_children(GTK_CONTAINER(window_button))[0].data );
             buttonlabel = GTK_WIDGET( g_list_nth_data( gtk_container_get_children(GTK_CONTAINER(buttonbox)), 1) );
-            gtk_label_set_text (GTK_LABEL (buttonlabel), "");
 
-            if (((Client *) g_object_get_data (G_OBJECT(window_button), "client-ptr-val")) == t->selected->data)
+            c = g_object_get_data (G_OBJECT (window_button), "client-ptr-val");
+
+            if (c != NULL)
             {
+                if (c->screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+                {
+                    gtk_label_set_text (GTK_LABEL (buttonlabel), "");
+                }
+
+                if (c == t->selected->data)
+                {
                     tabwinSetSelected (tbw, window_button, buttonlabel);
                     gtk_widget_queue_draw (GTK_WIDGET(tbw));
+                }
             }
         }
     }
@@ -769,6 +861,8 @@ tabwinSelectDelta (Tabwin *t, int row_delta, int col_delta)
     GList *selected;
     int pos_current, col_current, row_current, nitems, cols, rows;
     TabwinWidget *tbw;
+    Client *c;
+    ScreenInfo *screen_info;
 
     TRACE ("entering tabwinSelectDelta");
     g_return_val_if_fail (t != NULL, NULL);
@@ -777,10 +871,44 @@ tabwinSelectDelta (Tabwin *t, int row_delta, int col_delta)
     pos_current = g_list_position (*t->client_list, t->selected);
     nitems = g_list_length (*t->client_list);
 
-    cols = MIN (nitems, tbw->grid_cols);
-    rows = (nitems - 1) / cols + 1;
-    col_current = pos_current % cols;
-    row_current = pos_current / cols;
+    if (t->selected)
+    {
+        c = (Client *)t->selected->data;
+        screen_info = c->screen_info;
+        if (!screen_info)
+        {
+            return NULL;
+        }
+    }
+    else if (t->client_list)
+    {
+        c = (Client *)t->client_list;
+        screen_info = c->screen_info;
+        if (!screen_info)
+        {
+            return NULL;
+        }
+    }
+    else
+    {
+        /* There's no items? */
+        return NULL;
+    }
+
+    if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+    {
+        cols = MIN (nitems, tbw->grid_cols);
+        rows = (nitems - 1) / cols + 1;
+        col_current = pos_current % cols;
+        row_current = pos_current / cols;
+    }
+    else
+    {
+        rows = MIN (nitems, tbw->grid_rows);
+        cols = (nitems - 1) / rows + 1;
+        row_current = pos_current % rows;
+        col_current = pos_current / rows;
+    }
 
     /* Wrap column */
     col_current += col_delta;
@@ -797,10 +925,6 @@ tabwinSelectDelta (Tabwin *t, int row_delta, int col_delta)
     {
         col_current = 0;
         row_current++;
-        if (row_current >= rows)
-        {
-            row_current = rows - 1;
-        }
     }
 
     /* Wrap row */
@@ -834,21 +958,49 @@ tabwinSelectDelta (Tabwin *t, int row_delta, int col_delta)
     }
 
     /* So here we are at the new (wrapped) position in the rectangle */
-    pos_current = col_current + row_current * cols;
+    if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+    {
+        pos_current = col_current + row_current * cols;
+    }
+    else
+    {
+        pos_current = row_current + col_current * rows;
+    }
+
     if (pos_current >= nitems)   /* If that position does not exist */
     {
         if (col_delta)            /* Let horizontal prevail */
         {
             if (col_delta > 0)
             {
-                /* In this case we're going past the tail, reset to the head
-                 * of the grid */
-                col_current = 0;
-                row_current = 0;
+                if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+                {
+                    /* In this case we're going past the tail, reset to the head
+                     * of the grid */
+                    col_current = 0;
+                    row_current = 0;
+                }
+                else
+                {
+                    col_current = 0;
+                    row_current++;
+                    if (row_current >= rows)
+                    {
+                        row_current = 0;
+                    }
+                }
             }
             else
             {
-                col_current = (nitems - 1) % cols;
+                if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+                {
+                    col_current = (nitems - 1) % cols;
+                }
+                else
+                {
+                    col_current = cols - 1;
+                    row_current = (nitems - 1) % rows;
+                }
             }
         }
         else
@@ -864,11 +1016,27 @@ tabwinSelectDelta (Tabwin *t, int row_delta, int col_delta)
             }
             else
             {
-                row_current = row_current - 1;
+                if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+                {
+                    row_current = row_current - 1;
+                }
+                else
+                {
+                    row_current = (nitems - 1) % rows;
+                    col_current = cols - 1;
+                }
             }
 
         }
-        pos_current = col_current + row_current * cols;
+
+        if (screen_info->params->cycle_tabwin_mode == STANDARD_ICON_GRID)
+        {
+            pos_current = col_current + row_current * cols;
+        }
+        else
+        {
+            pos_current = row_current + col_current * rows;
+        }
     }
 
     selected = g_list_nth(*t->client_list, pos_current);
diff --git a/src/tabwin.h b/src/tabwin.h
index 67e5dd2..04d23f8 100644
--- a/src/tabwin.h
+++ b/src/tabwin.h
@@ -35,6 +35,13 @@ typedef struct _Tabwin Tabwin;
 typedef struct _TabwinWidget TabwinWidget;
 typedef struct _TabwinWidgetClass TabwinWidgetClass;
 
+typedef enum
+{
+    STANDARD_ICON_GRID,
+    OVERFLOW_COLUMN_GRID,
+}
+CYCLE_TABWIN_MODE;
+
 struct _Tabwin
 {
     GList *tabwin_list;


More information about the Xfce4-commits mailing list