]> Dogcows Code - chaz/openbox/commitdiff
a variable sized alt-tab box. is this nice or slower to read? we'll see.
authorDana Jansens <danakj@orodu.net>
Mon, 7 May 2007 03:54:39 +0000 (03:54 +0000)
committerDana Jansens <danakj@orodu.net>
Mon, 7 May 2007 03:54:39 +0000 (03:54 +0000)
openbox/focus.c

index eead6000dba9e41dcf2d9aeb56f6b080a7c2b2ca..afd4801b8073b7dcfddebec5e02a1035faa30164 100644 (file)
@@ -55,14 +55,10 @@ RrColor *color_white;
 
 static ObIconPopup *focus_cycle_popup;
 
-static void focus_cycle_destructor(ObClient *client, gpointer data)
-{
-    /* end cycling if the target disappears. CurrentTime is fine, time won't
-       be used
-    */
-    if (focus_cycle_target == client)
-        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
-}
+static gboolean valid_focus_target(ObClient *ft,
+                                   gboolean all_desktops,
+                                   gboolean dock_windows);
+static void focus_cycle_destructor(ObClient *client, gpointer data);
 
 static Window createWindow(Window parent, gulong mask,
                            XSetWindowAttributes *attrib)
@@ -289,49 +285,108 @@ void focus_nothing()
                    event_curtime);
 }
 
-static void popup_cycle(ObClient *c, gboolean show)
+static gchar *popup_get_name(ObClient *c, ObClient **nametarget)
+{
+    ObClient *p;
+    gchar *title = NULL;
+    const gchar *desk = NULL;
+    gchar *ret;
+
+    /* find our highest direct parent, including non-normal windows */
+    for (p = c; p->transient_for && p->transient_for != OB_TRAN_GROUP;
+         p = p->transient_for);
+    if (nametarget) *nametarget = p;
+
+    if (c->desktop != DESKTOP_ALL && c->desktop != screen_desktop)
+        desk = screen_desktop_names[c->desktop];
+
+    /* use the transient's parent's title/icon if we don't have one */
+    if (p != c && !strcmp("", (c->iconic ? c->icon_title : c->title)))
+        title = g_strdup(p->iconic ? p->icon_title : p->title);
+
+    if (title == NULL)
+        title = g_strdup(c->iconic ? c->icon_title : c->title);
+
+    if (desk)
+        ret = g_strdup_printf("%s [%s]", title, desk);
+    else {
+        ret = title;
+        title = NULL;
+    }
+    g_free(title);
+
+    return ret;
+}
+
+static void popup_cycle(ObClient *c, gboolean show,
+                        gboolean all_desktops, gboolean dock_windows)
 {
+    gchar *showtext = NULL;
+    ObClient *showtarget;
+
     if (!show) {
         icon_popup_hide(focus_cycle_popup);
-    } else {
+        return;
+    }
+
+    /* do this stuff only when the dialog is first showing */
+    if (!focus_cycle_popup->popup->mapped &&
+        !focus_cycle_popup->popup->delay_mapped)
+    {
         Rect *a;
-        ObClient *p;
-        gchar *text;
-        gchar *title = NULL;
-        const gchar *desk = NULL;
+        gchar **names;
+        GList *targets = NULL, *it;
+        gint n = 0, i;
 
+        /* position the popup */
         a = screen_physical_area_monitor(0);
         icon_popup_position(focus_cycle_popup, CenterGravity,
                             a->x + a->width / 2, a->y + a->height / 2);
-        icon_popup_width(focus_cycle_popup, MAX(a->width/3, POPUP_WIDTH));
         icon_popup_height(focus_cycle_popup, POPUP_HEIGHT);
 
-        /* find our highest direct parent, including non-normal windows */
-        for (p = c; p->transient_for && p->transient_for != OB_TRAN_GROUP;
-             p = p->transient_for);
-
-        if (c->desktop != DESKTOP_ALL && c->desktop != screen_desktop)
-            desk = screen_desktop_names[c->desktop];
+        /* make its width to be the width of all the possible titles */
 
-        /* use the transient's parent's title/icon if we don't have one */
-        if (p != c && !strcmp("", (c->iconic ? c->icon_title : c->title)))
-            title = g_strdup(p->iconic ? p->icon_title : p->title);
-            /*ptitle = g_strconcat((c->iconic ? c->icon_title : c->title),
-                                " - ",
-                                (p->iconic ? p->icon_title : p->title),
-                                NULL);
-            */
-        if (title == NULL)
-            title = g_strdup(c->iconic ? c->icon_title : c->title);
-        if (desk)
-            text = g_strdup_printf("%s [%s]", title, desk);
-        else
-            text = g_strdup(title);
+        /* build a list of all the valid focus targets */
+        for (it = focus_order; it; it = g_list_next(it)) {
+            ObClient *ft = it->data;
+            if (valid_focus_target(ft, all_desktops, dock_windows)) {
+                targets = g_list_prepend(targets, ft);
+                ++n;
+            }
+        }
+        /* make it null terminated so we can use g_strfreev */
+        names = g_new(char*, n+1);
+        for (it = targets, i = 0; it; it = g_list_next(it), ++i) {
+            ObClient *ft = it->data;
+            names[i] = popup_get_name(ft, &showtarget);
+
+            /* little optimization.. save this text so we dont have to get it
+               again */
+            if (ft == c)
+                showtext = g_strdup(names[i]);
+        }
+        names[n] = NULL;
 
-        icon_popup_show(focus_cycle_popup, text, client_icon(p, 48, 48));
-        g_free(text);
-        g_free(title);
+        icon_popup_width_to_strings(focus_cycle_popup,
+                                    names, n,
+                                    MAX(a->width/3, POPUP_WIDTH));
+        g_strfreev(names);
     }
+
+
+    if (!showtext) showtext = popup_get_name(c, &showtarget);
+    icon_popup_show(focus_cycle_popup, showtext,
+                    client_icon(showtarget, 48, 48));
+    g_free(showtext);
+}
+
+static void focus_cycle_destructor(ObClient *client, gpointer data)
+{
+    /* end cycling if the target disappears. CurrentTime is fine, time won't
+       be used
+    */
+    if (focus_cycle_target == client)
+        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
 }
 
 void focus_cycle_draw_indicator()
@@ -568,7 +623,8 @@ void focus_cycle(gboolean forward, gboolean all_desktops,
                     focus_cycle_target = ft;
                     focus_cycle_draw_indicator();
                 }
-                popup_cycle(ft, dialog);
+                /* same arguments as valid_focus_target */
+                popup_cycle(ft, dialog, all_desktops, dock_windows);
                 return;
             } else if (ft != focus_cycle_target) {
                 focus_cycle_target = ft;
@@ -590,14 +646,14 @@ done_cycle:
 
     if (interactive) {
         focus_cycle_draw_indicator();
-        popup_cycle(ft, FALSE);
+        popup_cycle(ft, FALSE, FALSE, FALSE);
     }
 
     return;
 }
 
 /* this be mostly ripped from fvwm */
-ObClient *focus_find_directional(ObClient *c, ObDirection dir,
+static ObClient *focus_find_directional(ObClient *c, ObDirection dir,
                                  gboolean dock_windows) 
 {
     gint my_cx, my_cy, his_cx, his_cy;
@@ -739,7 +795,8 @@ void focus_directional_cycle(ObDirection dir, gboolean dock_windows,
         }
     }
     if (focus_cycle_target) {
-        popup_cycle(focus_cycle_target, dialog);
+        /* same arguments as valid_focus_target */
+        popup_cycle(focus_cycle_target, dialog, FALSE, dock_windows);
         if (dialog)
             return;
     }
@@ -753,7 +810,7 @@ done_cycle:
     focus_cycle_target = NULL;
 
     focus_cycle_draw_indicator();
-    popup_cycle(ft, FALSE);
+    popup_cycle(ft, FALSE, FALSE, FALSE);
 
     return;
 }
This page took 0.028283 seconds and 4 git commands to generate.