+ 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 */
+ 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 interactive,
+ gboolean dialog, gboolean done, gboolean cancel)
+{
+ static ObClient *first = NULL;
+ static ObClient *t = NULL;
+ static GList *order = NULL;
+ GList *it, *start, *list;
+ ObClient *ft = NULL;
+
+ if (interactive) {
+ if (cancel) {
+ focus_cycle_target = NULL;
+ goto done_cycle;
+ } else if (done)
+ goto done_cycle;
+
+ if (!focus_order)
+ goto done_cycle;
+
+ if (!first) first = focus_client;
+
+ if (linear) list = client_list;
+ else list = focus_order;
+ } else {
+ if (!focus_order)
+ 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? */
+ start = it = forward ? g_list_last(list) : g_list_first(list);
+ if (!start) goto done_cycle;
+
+ do {
+ if (forward) {
+ it = it->next;
+ if (it == NULL) it = g_list_first(list);
+ } else {
+ it = it->prev;
+ if (it == NULL) it = g_list_last(list);
+ }
+ ft = it->data;
+ if (valid_focus_target(ft)) {
+ 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;
+ }
+ }
+ } while (it != start);
+
+done_cycle:
+ if (done && focus_cycle_target)
+ client_activate(focus_cycle_target, FALSE, TRUE);
+
+ t = NULL;
+ first = NULL;
+ focus_cycle_target = NULL;
+ g_list_free(order);
+ order = NULL;
+
+ if (interactive) {
+ focus_cycle_draw_indicator();
+ popup_cycle(ft, FALSE);
+ }
+
+ return;
+}
+
+void focus_directional_cycle(ObDirection dir, gboolean interactive,
+ gboolean dialog, gboolean done, gboolean cancel)
+{
+ static ObClient *first = NULL;
+ ObClient *ft = NULL;
+
+ if (!interactive)
+ return;
+
+ if (cancel) {
+ focus_cycle_target = NULL;
+ goto done_cycle;
+ } else if (done)
+ goto done_cycle;
+
+ if (!focus_order)
+ goto done_cycle;
+
+ if (!first) first = focus_client;
+ if (!focus_cycle_target) focus_cycle_target = focus_client;
+
+ if (focus_cycle_target)
+ ft = client_find_directional(focus_cycle_target, dir);
+ else {
+ GList *it;
+
+ for (it = focus_order; it; it = g_list_next(it))
+ if (valid_focus_target(it->data))
+ ft = it->data;
+ }
+
+ if (ft) {
+ if (ft != focus_cycle_target) {/* prevents flicker */
+ focus_cycle_target = ft;
+ focus_cycle_draw_indicator();
+ }
+ }
+ if (focus_cycle_target) {
+ popup_cycle(focus_cycle_target, dialog);
+ if (dialog)
+ return;
+ }
+
+
+done_cycle:
+ if (done && focus_cycle_target)
+ client_activate(focus_cycle_target, FALSE, TRUE);
+
+ first = NULL;
+ focus_cycle_target = NULL;
+
+ focus_cycle_draw_indicator();
+ popup_cycle(ft, FALSE);
+
+ return;
+}
+
+void focus_order_add_new(ObClient *c)
+{
+ if (c->iconic)
+ focus_order_to_top(c);
+ else {
+ g_assert(!g_list_find(focus_order, c));
+ /* if there are any iconic windows, put this above them in the order,
+ but if there are not, then put it under the currently focused one */
+ if (focus_order && ((ObClient*)focus_order->data)->iconic)
+ focus_order = g_list_insert(focus_order, c, 0);
+ else
+ focus_order = g_list_insert(focus_order, c, 1);
+ }
+}
+
+void focus_order_remove(ObClient *c)
+{
+ focus_order = g_list_remove(focus_order, c);
+}
+
+void focus_order_to_top(ObClient *c)
+{
+ focus_order = g_list_remove(focus_order, c);
+ if (!c->iconic) {
+ focus_order = g_list_prepend(focus_order, c);
+ } else {
+ GList *it;
+
+ /* insert before first iconic window */
+ for (it = focus_order;
+ it && !((ObClient*)it->data)->iconic; it = g_list_next(it));
+ focus_order = g_list_insert_before(focus_order, it, c);
+ }
+}
+
+void focus_order_to_bottom(ObClient *c)
+{
+ focus_order = g_list_remove(focus_order, c);
+ if (c->iconic) {
+ focus_order = g_list_append(focus_order, c);
+ } else {
+ GList *it;
+
+ /* insert before first iconic window */
+ for (it = focus_order;
+ it && !((ObClient*)it->data)->iconic; it = g_list_next(it));
+ focus_order = g_list_insert_before(focus_order, it, c);
+ }
+}
+
+ObClient *focus_order_find_first(guint desktop)
+{
+ GList *it;
+ for (it = focus_order; it; it = g_list_next(it)) {
+ ObClient *c = it->data;
+ if (c->desktop == desktop || c->desktop == DESKTOP_ALL)
+ return c;
+ }
+ return NULL;