]> Dogcows Code - chaz/openbox/blobdiff - openbox/focus.c
refix for managing iconic windows, without having the frame map which caused flashing.
[chaz/openbox] / openbox / focus.c
index 0140226ed5509c42b430f6834ea4b1e64e3e4a6b..201a43492bf88103c26c5f152d92e7becd0040c0 100644 (file)
@@ -1,7 +1,8 @@
 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
 
    focus.c for the Openbox window manager
-   Copyright (c) 2003        Ben Jansens
+   Copyright (c) 2006        Mikael Magnusson
+   Copyright (c) 2003-2007   Dana Jansens
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -49,23 +50,24 @@ struct {
 } focus_indicator;
 
 RrAppearance *a_focus_indicator;
-RrColor *color_black;
 RrColor *color_white;
 
 static ObIconPopup *focus_cycle_popup;
 
 static void focus_cycle_destructor(ObClient *client, gpointer data)
 {
-    /* end cycling if the target disappears */
+    /* 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);
+        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, CurrentTime);
 }
 
-static Window createWindow(Window parent, unsigned long mask,
-                          XSetWindowAttributes *attrib)
+static Window createWindow(Window parent, gulong mask,
+                           XSetWindowAttributes *attrib)
 {
     return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
-                        RrDepth(ob_rr_inst), InputOutput,
+                         RrDepth(ob_rr_inst), InputOutput,
                          RrVisual(ob_rr_inst), mask, attrib);
                        
 }
@@ -107,13 +109,13 @@ void focus_startup(gboolean reconfig)
         stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.right));
         stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.bottom));
 
-        color_black = RrColorNew(ob_rr_inst, 0, 0, 0);
         color_white = RrColorNew(ob_rr_inst, 0xff, 0xff, 0xff);
 
         a_focus_indicator = RrAppearanceNew(ob_rr_inst, 4);
         a_focus_indicator->surface.grad = RR_SURFACE_SOLID;
         a_focus_indicator->surface.relief = RR_RELIEF_FLAT;
-        a_focus_indicator->surface.primary = color_black;
+        a_focus_indicator->surface.primary = RrColorNew(ob_rr_inst,
+                                                        0, 0, 0);
         a_focus_indicator->texture[0].type = RR_TEXTURE_LINE_ART;
         a_focus_indicator->texture[0].data.lineart.color = color_white;
         a_focus_indicator->texture[1].type = RR_TEXTURE_LINE_ART;
@@ -139,9 +141,8 @@ void focus_shutdown(gboolean reconfig)
         g_free(focus_order);
 
         /* reset focus to root */
-        XSetInputFocus(ob_display, PointerRoot, RevertToNone, event_lasttime);
+        XSetInputFocus(ob_display, PointerRoot, RevertToNone, CurrentTime);
 
-        RrColorFree(color_black);
         RrColorFree(color_white);
 
         RrAppearanceFree(a_focus_indicator);
@@ -182,13 +183,15 @@ void focus_set_client(ObClient *client)
 #endif
         /* when nothing will be focused, send focus to the backup target */
         XSetInputFocus(ob_display, screen_support_win, RevertToNone,
-                       event_lasttime);
+                       event_curtime);
         XSync(ob_display, FALSE);
     }
 
-    /* in the middle of cycling..? kill it. */
+    /* in the middle of cycling..? kill it. CurrentTime is fine, time won't
+       be used.
+    */
     if (focus_cycle_target)
-        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE);
+        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, CurrentTime);
 
     old = focus_client;
     focus_client = client;
@@ -202,21 +205,30 @@ void focus_set_client(ObClient *client)
         active = client ? client->window : None;
         PROP_SET32(RootWindow(ob_display, ob_screen),
                    net_active_window, window, active);
+
+        /* remove hiliting from the window when it gets focused */
+        if (client != NULL)
+            client_hilite(client, FALSE);
     }
 }
 
 /* finds the first transient that isn't 'skip' and ensure's that client_normal
  is true for it */
-static ObClient *find_transient_recursive(ObClient *c, ObClient *top, ObClient *skip)
+static ObClient *find_transient_recursive(ObClient *c, ObClient *top,
+                                          ObClient *skip)
 {
     GSList *it;
     ObClient *ret;
 
-    for (it = c->transients; it; it = it->next) {
+    for (it = c->transients; it; it = g_slist_next(it)) {
         if (it->data == top) return NULL;
         ret = find_transient_recursive(it->data, top, skip);
-        if (ret && ret != skip && client_normal(ret)) return ret;
-        if (it->data != skip && client_normal(it->data)) return it->data;
+        if (ret && ret != skip && client_normal(ret) &&
+            client_can_focus(ret) && client_validate(ret))
+            return ret;
+        if (it->data != skip && client_normal(it->data) &&
+            client_can_focus(it->data) && client_validate(it->data))
+            return it->data;
     }
     return NULL;
 }
@@ -239,51 +251,65 @@ static ObClient* focus_fallback_transient(ObClient *top, ObClient *old)
 ObClient* focus_fallback_target(ObFocusFallbackType type)
 {
     GList *it;
-    ObClient *old = NULL;
+    ObClient *old;
     ObClient *target = NULL;
 
     old = focus_client;
 
-    if (type == OB_FOCUS_FALLBACK_UNFOCUSING && old) {
+    if ((type == OB_FOCUS_FALLBACK_UNFOCUSING
+         || type == OB_FOCUS_FALLBACK_CLOSED) && old) {
         if (old->transient_for) {
             gboolean trans = FALSE;
 
-            if (!config_focus_follow)
+            if (!config_focus_follow || config_focus_last)
+                trans = TRUE;
+            else if ((target = client_under_pointer()) &&
+                     client_search_transient
+                     (client_search_top_parent(target), old))
                 trans = TRUE;
-            else {
-                if ((target = client_under_pointer()) &&
-                    client_search_transient
-                    (client_search_top_transient(target), old))
-                {
-                    trans = TRUE;
-                }
-            }
 
             /* try for transient relations */
             if (trans) {
                 if (old->transient_for == OB_TRAN_GROUP) {
-                    for (it = focus_order[screen_desktop]; it; it = it->next) {
+                    for (it = focus_order[screen_desktop]; it;
+                         it = g_list_next(it))
+                    {
                         GSList *sit;
 
-                        for (sit = old->group->members; sit; sit = sit->next)
+                        for (sit = old->group->members; sit;
+                             sit = g_slist_next(sit))
+                        {
                             if (sit->data == it->data)
                                 if ((target =
                                      focus_fallback_transient(sit->data, old)))
+                                {
+                                    ob_debug("found in transient #1\n");
                                     return target;
+                                }
+                        }
                     }
                 } else {
                     if ((target =
                          focus_fallback_transient(old->transient_for, old)))
+                    {
+                        ob_debug("found in transient #2\n");
                         return target;
+                    }
                 }
             }
         }
     }
 
-    if (config_focus_follow) {
+    ob_debug("trying pointer stuff\n");
+    if (config_focus_follow &&
+        (type == OB_FOCUS_FALLBACK_UNFOCUSING || !config_focus_last))
+    {
         if ((target = client_under_pointer()))
-            if (client_normal(target) && client_can_focus(target))
+            if (client_normal(target) && client_can_focus(target) &&
+                client_validate(target)) {
+                ob_debug("found in pointer stuff\n");
                 return target;
+            }
     }
 
 #if 0
@@ -291,8 +317,8 @@ ObClient* focus_fallback_target(ObFocusFallbackType type)
         if (old->group) {
             GSList *sit;
 
-            for (it = focus_order[screen_desktop]; it != NULL; it = it->next)
-                for (sit = old->group->members; sit; sit = sit->next)
+            for (it = focus_order[screen_desktop]; it; it = g_list_next(it))
+                for (sit = old->group->members; sit; sit = g_slist_next(sit))
                     if (sit->data == it->data)
                         if (sit->data != old && client_normal(sit->data))
                             if (client_can_focus(sit->data))
@@ -300,10 +326,20 @@ ObClient* focus_fallback_target(ObFocusFallbackType type)
         }
 #endif
 
-    for (it = focus_order[screen_desktop]; it != NULL; it = it->next)
+    ob_debug("trying  the focus order\n");
+    for (it = focus_order[screen_desktop]; it; it = g_list_next(it))
         if (type != OB_FOCUS_FALLBACK_UNFOCUSING || it->data != old)
-            if (client_normal(it->data) && client_can_focus(it->data))
+            if (client_normal(it->data) && client_can_focus(it->data) &&
+                client_validate(it->data))
+            {
+                ob_debug("found in focus order\n");
                 return it->data;
+            }
+
+    /* XXX fallback to the "desktop window" if one exists ?
+       could store it while going through all the windows in the loop right
+       above this..
+    */
 
     return NULL;
 }
@@ -329,7 +365,7 @@ static void popup_cycle(ObClient *c, gboolean show)
     } else {
         Rect *a;
         ObClient *p = c;
-        char *title;
+        gchar *title = NULL;
 
         a = screen_physical_area_monitor(0);
         icon_popup_position(focus_cycle_popup, CenterGravity,
@@ -346,14 +382,13 @@ static void popup_cycle(ObClient *c, gboolean show)
         while (p->transient_for && p->transient_for != OB_TRAN_GROUP)
             p = p->transient_for;
 
-        if (p == c)
-            title = NULL;
-        else
-            title = g_strconcat((c->iconic ? c->icon_title : c->title),
+        if (p != c && !strcmp("", (c->iconic ? c->icon_title : c->title)))
+            title = g_strdup(p->iconic ? p->icon_title : p->title);
+            /*title = g_strconcat((c->iconic ? c->icon_title : c->title),
                                 " - ",
                                 (p->iconic ? p->icon_title : p->title),
                                 NULL);
-
+            */
         icon_popup_show(focus_cycle_popup,
                         (title ? title :
                          (c->iconic ? c->icon_title : c->title)),
@@ -362,20 +397,176 @@ static void popup_cycle(ObClient *c, gboolean show)
     }
 }
 
+void focus_cycle_draw_indicator()
+{
+    if (!focus_cycle_target) {
+        XUnmapWindow(ob_display, focus_indicator.top.win);
+        XUnmapWindow(ob_display, focus_indicator.left.win);
+        XUnmapWindow(ob_display, focus_indicator.right.win);
+        XUnmapWindow(ob_display, focus_indicator.bottom.win);
+    } else {
+        /*
+          if (focus_cycle_target)
+              frame_adjust_focus(focus_cycle_target->frame, FALSE);
+          frame_adjust_focus(focus_cycle_target->frame, TRUE);
+        */
+        gint x, y, w, h;
+        gint wt, wl, wr, wb;
+
+        wt = wl = wr = wb = MAX(3,
+                                MAX(1, MAX(ob_rr_theme->paddingx,
+                                           ob_rr_theme->paddingy)) * 2 +
+                                ob_rr_theme->fbwidth * 2);
+
+        x = focus_cycle_target->frame->area.x;
+        y = focus_cycle_target->frame->area.y;
+        w = focus_cycle_target->frame->area.width;
+        h = wt;
+
+        XMoveResizeWindow(ob_display, focus_indicator.top.win,
+                          x, y, w, h);
+        a_focus_indicator->texture[0].data.lineart.x1 = 0;
+        a_focus_indicator->texture[0].data.lineart.y1 = h-1;
+        a_focus_indicator->texture[0].data.lineart.x2 = 0;
+        a_focus_indicator->texture[0].data.lineart.y2 = 0;
+        a_focus_indicator->texture[1].data.lineart.x1 = 0;
+        a_focus_indicator->texture[1].data.lineart.y1 = 0;
+        a_focus_indicator->texture[1].data.lineart.x2 = w-1;
+        a_focus_indicator->texture[1].data.lineart.y2 = 0;
+        a_focus_indicator->texture[2].data.lineart.x1 = w-1;
+        a_focus_indicator->texture[2].data.lineart.y1 = 0;
+        a_focus_indicator->texture[2].data.lineart.x2 = w-1;
+        a_focus_indicator->texture[2].data.lineart.y2 = h-1;
+        a_focus_indicator->texture[3].data.lineart.x1 = (wl-1);
+        a_focus_indicator->texture[3].data.lineart.y1 = h-1;
+        a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
+        a_focus_indicator->texture[3].data.lineart.y2 = h-1;
+        RrPaint(a_focus_indicator, focus_indicator.top.win,
+                w, h);
+
+        x = focus_cycle_target->frame->area.x;
+        y = focus_cycle_target->frame->area.y;
+        w = wl;
+        h = focus_cycle_target->frame->area.height;
+
+        XMoveResizeWindow(ob_display, focus_indicator.left.win,
+                          x, y, w, h);
+        a_focus_indicator->texture[0].data.lineart.x1 = w-1;
+        a_focus_indicator->texture[0].data.lineart.y1 = 0;
+        a_focus_indicator->texture[0].data.lineart.x2 = 0;
+        a_focus_indicator->texture[0].data.lineart.y2 = 0;
+        a_focus_indicator->texture[1].data.lineart.x1 = 0;
+        a_focus_indicator->texture[1].data.lineart.y1 = 0;
+        a_focus_indicator->texture[1].data.lineart.x2 = 0;
+        a_focus_indicator->texture[1].data.lineart.y2 = h-1;
+        a_focus_indicator->texture[2].data.lineart.x1 = 0;
+        a_focus_indicator->texture[2].data.lineart.y1 = h-1;
+        a_focus_indicator->texture[2].data.lineart.x2 = w-1;
+        a_focus_indicator->texture[2].data.lineart.y2 = h-1;
+        a_focus_indicator->texture[3].data.lineart.x1 = w-1;
+        a_focus_indicator->texture[3].data.lineart.y1 = wt-1;
+        a_focus_indicator->texture[3].data.lineart.x2 = w-1;
+        a_focus_indicator->texture[3].data.lineart.y2 = h - wb;
+        RrPaint(a_focus_indicator, focus_indicator.left.win,
+                w, h);
+
+        x = focus_cycle_target->frame->area.x +
+            focus_cycle_target->frame->area.width - wr;
+        y = focus_cycle_target->frame->area.y;
+        w = wr;
+        h = focus_cycle_target->frame->area.height ;
+
+        XMoveResizeWindow(ob_display, focus_indicator.right.win,
+                          x, y, w, h);
+        a_focus_indicator->texture[0].data.lineart.x1 = 0;
+        a_focus_indicator->texture[0].data.lineart.y1 = 0;
+        a_focus_indicator->texture[0].data.lineart.x2 = w-1;
+        a_focus_indicator->texture[0].data.lineart.y2 = 0;
+        a_focus_indicator->texture[1].data.lineart.x1 = w-1;
+        a_focus_indicator->texture[1].data.lineart.y1 = 0;
+        a_focus_indicator->texture[1].data.lineart.x2 = w-1;
+        a_focus_indicator->texture[1].data.lineart.y2 = h-1;
+        a_focus_indicator->texture[2].data.lineart.x1 = w-1;
+        a_focus_indicator->texture[2].data.lineart.y1 = h-1;
+        a_focus_indicator->texture[2].data.lineart.x2 = 0;
+        a_focus_indicator->texture[2].data.lineart.y2 = h-1;
+        a_focus_indicator->texture[3].data.lineart.x1 = 0;
+        a_focus_indicator->texture[3].data.lineart.y1 = wt-1;
+        a_focus_indicator->texture[3].data.lineart.x2 = 0;
+        a_focus_indicator->texture[3].data.lineart.y2 = h - wb;
+        RrPaint(a_focus_indicator, focus_indicator.right.win,
+                w, h);
+
+        x = focus_cycle_target->frame->area.x;
+        y = focus_cycle_target->frame->area.y +
+            focus_cycle_target->frame->area.height - wb;
+        w = focus_cycle_target->frame->area.width;
+        h = wb;
+
+        XMoveResizeWindow(ob_display, focus_indicator.bottom.win,
+                          x, y, w, h);
+        a_focus_indicator->texture[0].data.lineart.x1 = 0;
+        a_focus_indicator->texture[0].data.lineart.y1 = 0;
+        a_focus_indicator->texture[0].data.lineart.x2 = 0;
+        a_focus_indicator->texture[0].data.lineart.y2 = h-1;
+        a_focus_indicator->texture[1].data.lineart.x1 = 0;
+        a_focus_indicator->texture[1].data.lineart.y1 = h-1;
+        a_focus_indicator->texture[1].data.lineart.x2 = w-1;
+        a_focus_indicator->texture[1].data.lineart.y2 = h-1;
+        a_focus_indicator->texture[2].data.lineart.x1 = w-1;
+        a_focus_indicator->texture[2].data.lineart.y1 = h-1;
+        a_focus_indicator->texture[2].data.lineart.x2 = w-1;
+        a_focus_indicator->texture[2].data.lineart.y2 = 0;
+        a_focus_indicator->texture[3].data.lineart.x1 = wl-1;
+        a_focus_indicator->texture[3].data.lineart.y1 = 0;
+        a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
+        a_focus_indicator->texture[3].data.lineart.y2 = 0;
+        RrPaint(a_focus_indicator, focus_indicator.bottom.win,
+                w, h);
+
+        XMapWindow(ob_display, focus_indicator.top.win);
+        XMapWindow(ob_display, focus_indicator.left.win);
+        XMapWindow(ob_display, focus_indicator.right.win);
+        XMapWindow(ob_display, focus_indicator.bottom.win);
+    }
+}
+
 static gboolean valid_focus_target(ObClient *ft)
 {
     /* we don't use client_can_focus here, because that doesn't let you
        focus an iconic window, but we want to be able to, so we just check
        if the focus flags on the window allow it, and its on the current
        desktop */
-    return (!ft->transients && client_normal(ft) &&
-            ((ft->can_focus || ft->focus_notify) &&
-             !ft->skip_taskbar &&
-             (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)));
+    if ((ft->type == OB_CLIENT_TYPE_NORMAL ||
+         ft->type == OB_CLIENT_TYPE_DIALOG ||
+         (!client_has_group_siblings(ft) &&
+          (ft->type == OB_CLIENT_TYPE_TOOLBAR ||
+           ft->type == OB_CLIENT_TYPE_MENU ||
+           ft->type == OB_CLIENT_TYPE_UTILITY))) &&
+        ((ft->can_focus || ft->focus_notify) &&
+         !ft->skip_pager &&
+         (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)) &&
+        ft == client_focus_target(ft))
+        return TRUE;
+/*
+    {
+        GSList *it;
+
+        for (it = ft->transients; it; it = g_slist_next(it)) {
+            ObClient *c = it->data;
+
+            if (c->frame->visible)
+                return FALSE;
+        }
+        return TRUE;
+    }
+*/
+
+    return FALSE;
 }
 
-void focus_cycle(gboolean forward, gboolean linear,
-                 gboolean dialog, gboolean done, gboolean cancel)
+void focus_cycle(gboolean forward, gboolean linear, gboolean interactive,
+                 gboolean dialog, gboolean done, gboolean cancel, Time time)
 {
     static ObClient *first = NULL;
     static ObClient *t = NULL;
@@ -383,27 +574,26 @@ void focus_cycle(gboolean forward, gboolean linear,
     GList *it, *start, *list;
     ObClient *ft = NULL;
 
-    if (cancel) {
-        /*
-        if (focus_cycle_target)
-            frame_adjust_focus(focus_cycle_target->frame, FALSE);
-        if (focus_client)
-            frame_adjust_focus(focus_client->frame, TRUE);
-        */
-        focus_cycle_target = NULL;
-        goto done_cycle;
-    } else if (done && dialog) {
-        goto done_cycle;
-    }
+    if (interactive) {
+        if (cancel) {
+            focus_cycle_target = NULL;
+            goto done_cycle;
+        } else if (done)
+            goto done_cycle;
 
-    if (!focus_order[screen_desktop])
-        goto done_cycle;
+        if (!focus_order[screen_desktop])
+            goto done_cycle;
 
-    if (!first) first = focus_client;
-    if (!focus_cycle_target) focus_cycle_target = focus_client;
+        if (!first) first = focus_client;
 
-    if (linear) list = client_list;
-    else        list = focus_order[screen_desktop];
+        if (linear) list = client_list;
+        else        list = focus_order[screen_desktop];
+    } else {
+        if (!focus_order[screen_desktop])
+            goto done_cycle;
+        list = client_list;
+    }
+    if (!focus_cycle_target) focus_cycle_target = focus_client;
 
     start = it = g_list_find(list, focus_cycle_target);
     if (!start) /* switched desktops or something? */
@@ -420,145 +610,24 @@ void focus_cycle(gboolean forward, gboolean linear,
         }
         ft = it->data;
         if (valid_focus_target(ft)) {
-            if (ft != focus_cycle_target) { /* prevents flicker */
-                /*
-                if (focus_cycle_target)
-                    frame_adjust_focus(focus_cycle_target->frame, FALSE);
-                */
-                focus_cycle_target = ft;
-                /*
-                frame_adjust_focus(focus_cycle_target->frame, TRUE);
-                */
-                {
-                    int x, y, w, h;
-                    int wt, wl, wr, wb;
-
-                    wt = wl = wr = wb = MAX(5, ob_rr_theme->handle_height);
-
-                    x = focus_cycle_target->frame->area.x;
-                    y = focus_cycle_target->frame->area.y;
-                    w = focus_cycle_target->frame->area.width;
-                    h = wt;
-
-                    XMoveResizeWindow(ob_display, focus_indicator.top.win,
-                                      x, y, w, h);
-                    a_focus_indicator->texture[0].data.lineart.x1 = 0;
-                    a_focus_indicator->texture[0].data.lineart.y1 = h-1;
-                    a_focus_indicator->texture[0].data.lineart.x2 = 0;
-                    a_focus_indicator->texture[0].data.lineart.y2 = 0;
-                    a_focus_indicator->texture[1].data.lineart.x1 = 0;
-                    a_focus_indicator->texture[1].data.lineart.y1 = 0;
-                    a_focus_indicator->texture[1].data.lineart.x2 = w-1;
-                    a_focus_indicator->texture[1].data.lineart.y2 = 0;
-                    a_focus_indicator->texture[2].data.lineart.x1 = w-1;
-                    a_focus_indicator->texture[2].data.lineart.y1 = 0;
-                    a_focus_indicator->texture[2].data.lineart.x2 = w-1;
-                    a_focus_indicator->texture[2].data.lineart.y2 = h-1;
-                    a_focus_indicator->texture[3].data.lineart.x1 = (wl-1);
-                    a_focus_indicator->texture[3].data.lineart.y1 = h-1;
-                    a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
-                    a_focus_indicator->texture[3].data.lineart.y2 = h-1;
-                    RrPaint(a_focus_indicator, focus_indicator.top.win,
-                            w, h);
-
-                    x = focus_cycle_target->frame->area.x;
-                    y = focus_cycle_target->frame->area.y;
-                    w = wl;
-                    h = focus_cycle_target->frame->area.height;
-
-                    XMoveResizeWindow(ob_display, focus_indicator.left.win,
-                                      x, y, w, h);
-                    a_focus_indicator->texture[0].data.lineart.x1 = w-1;
-                    a_focus_indicator->texture[0].data.lineart.y1 = 0;
-                    a_focus_indicator->texture[0].data.lineart.x2 = 0;
-                    a_focus_indicator->texture[0].data.lineart.y2 = 0;
-                    a_focus_indicator->texture[1].data.lineart.x1 = 0;
-                    a_focus_indicator->texture[1].data.lineart.y1 = 0;
-                    a_focus_indicator->texture[1].data.lineart.x2 = 0;
-                    a_focus_indicator->texture[1].data.lineart.y2 = h-1;
-                    a_focus_indicator->texture[2].data.lineart.x1 = 0;
-                    a_focus_indicator->texture[2].data.lineart.y1 = h-1;
-                    a_focus_indicator->texture[2].data.lineart.x2 = w-1;
-                    a_focus_indicator->texture[2].data.lineart.y2 = h-1;
-                    a_focus_indicator->texture[3].data.lineart.x1 = w-1;
-                    a_focus_indicator->texture[3].data.lineart.y1 = wt-1;
-                    a_focus_indicator->texture[3].data.lineart.x2 = w-1;
-                    a_focus_indicator->texture[3].data.lineart.y2 = h - wb;
-                    RrPaint(a_focus_indicator, focus_indicator.left.win,
-                            w, h);
-
-                    x = focus_cycle_target->frame->area.x +
-                        focus_cycle_target->frame->area.width - wr;
-                    y = focus_cycle_target->frame->area.y;
-                    w = wr;
-                    h = focus_cycle_target->frame->area.height ;
-
-                    XMoveResizeWindow(ob_display, focus_indicator.right.win,
-                                      x, y, w, h);
-                    a_focus_indicator->texture[0].data.lineart.x1 = 0;
-                    a_focus_indicator->texture[0].data.lineart.y1 = 0;
-                    a_focus_indicator->texture[0].data.lineart.x2 = w-1;
-                    a_focus_indicator->texture[0].data.lineart.y2 = 0;
-                    a_focus_indicator->texture[1].data.lineart.x1 = w-1;
-                    a_focus_indicator->texture[1].data.lineart.y1 = 0;
-                    a_focus_indicator->texture[1].data.lineart.x2 = w-1;
-                    a_focus_indicator->texture[1].data.lineart.y2 = h-1;
-                    a_focus_indicator->texture[2].data.lineart.x1 = w-1;
-                    a_focus_indicator->texture[2].data.lineart.y1 = h-1;
-                    a_focus_indicator->texture[2].data.lineart.x2 = 0;
-                    a_focus_indicator->texture[2].data.lineart.y2 = h-1;
-                    a_focus_indicator->texture[3].data.lineart.x1 = 0;
-                    a_focus_indicator->texture[3].data.lineart.y1 = wt-1;
-                    a_focus_indicator->texture[3].data.lineart.x2 = 0;
-                    a_focus_indicator->texture[3].data.lineart.y2 = h - wb;
-                    RrPaint(a_focus_indicator, focus_indicator.right.win,
-                            w, h);
-
-                    x = focus_cycle_target->frame->area.x;
-                    y = focus_cycle_target->frame->area.y +
-                        focus_cycle_target->frame->area.height - wb;
-                    w = focus_cycle_target->frame->area.width;
-                    h = wb;
-
-                    XMoveResizeWindow(ob_display, focus_indicator.bottom.win,
-                                      x, y, w, h);
-                    a_focus_indicator->texture[0].data.lineart.x1 = 0;
-                    a_focus_indicator->texture[0].data.lineart.y1 = 0;
-                    a_focus_indicator->texture[0].data.lineart.x2 = 0;
-                    a_focus_indicator->texture[0].data.lineart.y2 = h-1;
-                    a_focus_indicator->texture[1].data.lineart.x1 = 0;
-                    a_focus_indicator->texture[1].data.lineart.y1 = h-1;
-                    a_focus_indicator->texture[1].data.lineart.x2 = w-1;
-                    a_focus_indicator->texture[1].data.lineart.y2 = h-1;
-                    a_focus_indicator->texture[2].data.lineart.x1 = w-1;
-                    a_focus_indicator->texture[2].data.lineart.y1 = h-1;
-                    a_focus_indicator->texture[2].data.lineart.x2 = w-1;
-                    a_focus_indicator->texture[2].data.lineart.y2 = 0;
-                    a_focus_indicator->texture[3].data.lineart.x1 = wl-1;
-                    a_focus_indicator->texture[3].data.lineart.y1 = 0;
-                    a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
-                    a_focus_indicator->texture[3].data.lineart.y2 = 0;
-                    RrPaint(a_focus_indicator, focus_indicator.bottom.win,
-                            w, h);
+            if (interactive) {
+                if (ft != focus_cycle_target) { /* prevents flicker */
+                    focus_cycle_target = ft;
+                    focus_cycle_draw_indicator();
                 }
+                popup_cycle(ft, dialog);
+                return;
+            } else if (ft != focus_cycle_target) {
+                focus_cycle_target = ft;
+                done = TRUE;
+                break;
             }
-            popup_cycle(ft, dialog);
-            XMapWindow(ob_display, focus_indicator.top.win);
-            XMapWindow(ob_display, focus_indicator.left.win);
-            XMapWindow(ob_display, focus_indicator.right.win);
-            XMapWindow(ob_display, focus_indicator.bottom.win);
-            return;
         }
     } while (it != start);
 
 done_cycle:
     if (done && focus_cycle_target)
-        client_activate(focus_cycle_target, FALSE);
-
-    XUnmapWindow(ob_display, focus_indicator.top.win);
-    XUnmapWindow(ob_display, focus_indicator.left.win);
-    XUnmapWindow(ob_display, focus_indicator.right.win);
-    XUnmapWindow(ob_display, focus_indicator.bottom.win);
+        client_activate(focus_cycle_target, FALSE, TRUE, time);
 
     t = NULL;
     first = NULL;
@@ -566,27 +635,29 @@ done_cycle:
     g_list_free(order);
     order = NULL;
 
-    popup_cycle(ft, FALSE);
+    if (interactive) {
+        focus_cycle_draw_indicator();
+        popup_cycle(ft, FALSE);
+    }
 
     return;
 }
 
-void focus_directional_cycle(ObDirection dir,
-                             gboolean dialog, gboolean done, gboolean cancel)
+void focus_directional_cycle(ObDirection dir, gboolean interactive,
+                             gboolean dialog, gboolean done, gboolean cancel,
+                             Time time)
 {
     static ObClient *first = NULL;
     ObClient *ft = NULL;
 
+    if (!interactive)
+        return;
+
     if (cancel) {
-        if (focus_cycle_target)
-            frame_adjust_focus(focus_cycle_target->frame, FALSE);
-        if (focus_client)
-            frame_adjust_focus(focus_client->frame, TRUE);
         focus_cycle_target = NULL;
         goto done_cycle;
-    } else if (done && dialog) {
+    } else if (done)
         goto done_cycle;
-    }
 
     if (!focus_order[screen_desktop])
         goto done_cycle;
@@ -606,10 +677,8 @@ void focus_directional_cycle(ObDirection dir,
         
     if (ft) {
         if (ft != focus_cycle_target) {/* prevents flicker */
-            if (focus_cycle_target)
-                frame_adjust_focus(focus_cycle_target->frame, FALSE);
             focus_cycle_target = ft;
-            frame_adjust_focus(focus_cycle_target->frame, TRUE);
+            focus_cycle_draw_indicator();
         }
     }
     if (focus_cycle_target) {
@@ -621,11 +690,12 @@ void focus_directional_cycle(ObDirection dir,
 
 done_cycle:
     if (done && focus_cycle_target)
-        client_activate(focus_cycle_target, FALSE);
+        client_activate(focus_cycle_target, FALSE, TRUE, time);
 
     first = NULL;
     focus_cycle_target = NULL;
 
+    focus_cycle_draw_indicator();
     popup_cycle(ft, FALSE);
 
     return;
@@ -641,16 +711,19 @@ void focus_order_add_new(ObClient *c)
         d = c->desktop;
         if (d == DESKTOP_ALL) {
             for (i = 0; i < screen_num_desktops; ++i) {
+                g_assert(!g_list_find(focus_order[i], c));
                 if (focus_order[i] && ((ObClient*)focus_order[i]->data)->iconic)
                     focus_order[i] = g_list_insert(focus_order[i], c, 0);
                 else
                     focus_order[i] = g_list_insert(focus_order[i], c, 1);
             }
-        } else
-             if (focus_order[d] && ((ObClient*)focus_order[d]->data)->iconic)
+        } else {
+            g_assert(!g_list_find(focus_order[d], c));
+            if (focus_order[d] && ((ObClient*)focus_order[d]->data)->iconic)
                 focus_order[d] = g_list_insert(focus_order[d], c, 0);
             else
                 focus_order[d] = g_list_insert(focus_order[d], c, 1);
+        }
     }
 }
 
@@ -676,7 +749,7 @@ static void to_top(ObClient *c, guint d)
 
         /* insert before first iconic window */
         for (it = focus_order[d];
-             it && !((ObClient*)it->data)->iconic; it = it->next);
+             it && !((ObClient*)it->data)->iconic; it = g_list_next(it));
         focus_order[d] = g_list_insert_before(focus_order[d], it, c);
     }
 }
@@ -703,8 +776,8 @@ static void to_bottom(ObClient *c, guint d)
 
         /* insert before first iconic window */
         for (it = focus_order[d];
-             it && !((ObClient*)it->data)->iconic; it = it->next);
-        g_list_insert_before(focus_order[d], it, c);
+             it && !((ObClient*)it->data)->iconic; it = g_list_next(it));
+        focus_order[d] = g_list_insert_before(focus_order[d], it, c);
     }
 }
 
This page took 0.036708 seconds and 4 git commands to generate.