]> Dogcows Code - chaz/openbox/blobdiff - openbox/focus.c
woot sexy
[chaz/openbox] / openbox / focus.c
index 97dfcd7a3275247b5747d16fe4f45dedc39c68ad..013474d779ccb08ad3d8f199d02c0235510b36ea 100644 (file)
@@ -30,6 +30,7 @@
 #include "focus.h"
 #include "stacking.h"
 #include "popup.h"
 #include "focus.h"
 #include "stacking.h"
 #include "popup.h"
+#include "render/render.h"
 
 #include <X11/Xlib.h>
 #include <glib.h>
 
 #include <X11/Xlib.h>
 #include <glib.h>
@@ -40,6 +41,16 @@ GList **focus_order; /* these lists are created when screen_startup
                         sets the number of desktops */
 ObClient *focus_cycle_target;
 
                         sets the number of desktops */
 ObClient *focus_cycle_target;
 
+struct {
+    InternalWindow top;
+    InternalWindow left;
+    InternalWindow right;
+    InternalWindow bottom;
+} focus_indicator;
+
+RrAppearance *a_focus_indicator;
+RrColor *color_white;
+
 static ObIconPopup *focus_cycle_popup;
 
 static void focus_cycle_destructor(ObClient *client, gpointer data)
 static ObIconPopup *focus_cycle_popup;
 
 static void focus_cycle_destructor(ObClient *client, gpointer data)
@@ -49,15 +60,67 @@ static void focus_cycle_destructor(ObClient *client, gpointer data)
         focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE);
 }
 
         focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE);
 }
 
+static Window createWindow(Window parent, unsigned long mask,
+                          XSetWindowAttributes *attrib)
+{
+    return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
+                        RrDepth(ob_rr_inst), InputOutput,
+                         RrVisual(ob_rr_inst), mask, attrib);
+                       
+}
+
 void focus_startup(gboolean reconfig)
 {
     focus_cycle_popup = icon_popup_new(TRUE);
 
     if (!reconfig) {
 void focus_startup(gboolean reconfig)
 {
     focus_cycle_popup = icon_popup_new(TRUE);
 
     if (!reconfig) {
+        XSetWindowAttributes attr;
+
         client_add_destructor(focus_cycle_destructor, NULL);
 
         /* start with nothing focused */
         focus_set_client(NULL);
         client_add_destructor(focus_cycle_destructor, NULL);
 
         /* start with nothing focused */
         focus_set_client(NULL);
+
+        focus_indicator.top.obwin.type = Window_Internal;
+        focus_indicator.left.obwin.type = Window_Internal;
+        focus_indicator.right.obwin.type = Window_Internal;
+        focus_indicator.bottom.obwin.type = Window_Internal;
+
+        attr.override_redirect = True;
+        attr.background_pixel = BlackPixel(ob_display, ob_screen);
+        focus_indicator.top.win =
+            createWindow(RootWindow(ob_display, ob_screen),
+                         CWOverrideRedirect | CWBackPixel, &attr);
+        focus_indicator.left.win =
+            createWindow(RootWindow(ob_display, ob_screen),
+                         CWOverrideRedirect | CWBackPixel, &attr);
+        focus_indicator.right.win =
+            createWindow(RootWindow(ob_display, ob_screen),
+                         CWOverrideRedirect | CWBackPixel, &attr);
+        focus_indicator.bottom.win =
+            createWindow(RootWindow(ob_display, ob_screen),
+                         CWOverrideRedirect | CWBackPixel, &attr);
+
+        stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.top));
+        stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.left));
+        stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.right));
+        stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.bottom));
+
+        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 = 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;
+        a_focus_indicator->texture[1].data.lineart.color = color_white;
+        a_focus_indicator->texture[2].type = RR_TEXTURE_LINE_ART;
+        a_focus_indicator->texture[2].data.lineart.color = color_white;
+        a_focus_indicator->texture[3].type = RR_TEXTURE_LINE_ART;
+        a_focus_indicator->texture[3].data.lineart.color = color_white;
     }
 }
 
     }
 }
 
@@ -76,6 +139,15 @@ void focus_shutdown(gboolean reconfig)
 
         /* reset focus to root */
         XSetInputFocus(ob_display, PointerRoot, RevertToNone, event_lasttime);
 
         /* reset focus to root */
         XSetInputFocus(ob_display, PointerRoot, RevertToNone, event_lasttime);
+
+        RrColorFree(color_white);
+
+        RrAppearanceFree(a_focus_indicator);
+
+        XDestroyWindow(ob_display, focus_indicator.top.win);
+        XDestroyWindow(ob_display, focus_indicator.left.win);
+        XDestroyWindow(ob_display, focus_indicator.right.win);
+        XDestroyWindow(ob_display, focus_indicator.bottom.win);
     }
 }
 
     }
 }
 
@@ -288,13 +360,152 @@ 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);
+        */
+        int x, y, w, h;
+        int wt, wl, wr, wb;
+
+        wt = wl = wr = wb = MAX(3,
+                                ob_rr_theme->handle_height +
+                                ob_rr_theme->bwidth * 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 */
 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) &&
+    return ((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->transients &&
             ((ft->can_focus || ft->focus_notify) &&
              !ft->skip_taskbar &&
              (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)));
             ((ft->can_focus || ft->focus_notify) &&
              !ft->skip_taskbar &&
              (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)));
@@ -310,15 +521,10 @@ void focus_cycle(gboolean forward, gboolean linear,
     ObClient *ft = NULL;
 
     if (cancel) {
     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;
         focus_cycle_target = NULL;
         goto done_cycle;
-    } else if (done && dialog) {
+    } else if (done)
         goto done_cycle;
         goto done_cycle;
-    }
 
     if (!focus_order[screen_desktop])
         goto done_cycle;
 
     if (!focus_order[screen_desktop])
         goto done_cycle;
@@ -345,10 +551,8 @@ void focus_cycle(gboolean forward, gboolean linear,
         ft = it->data;
         if (valid_focus_target(ft)) {
             if (ft != focus_cycle_target) { /* prevents flicker */
         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;
                 focus_cycle_target = ft;
-                frame_adjust_focus(focus_cycle_target->frame, TRUE);
+                focus_cycle_draw_indicator();
             }
             popup_cycle(ft, dialog);
             return;
             }
             popup_cycle(ft, dialog);
             return;
@@ -365,6 +569,7 @@ done_cycle:
     g_list_free(order);
     order = NULL;
 
     g_list_free(order);
     order = NULL;
 
+    focus_cycle_draw_indicator();
     popup_cycle(ft, FALSE);
 
     return;
     popup_cycle(ft, FALSE);
 
     return;
@@ -377,15 +582,10 @@ void focus_directional_cycle(ObDirection dir,
     ObClient *ft = NULL;
 
     if (cancel) {
     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;
         focus_cycle_target = NULL;
         goto done_cycle;
-    } else if (done && dialog) {
+    } else if (done)
         goto done_cycle;
         goto done_cycle;
-    }
 
     if (!focus_order[screen_desktop])
         goto done_cycle;
 
     if (!focus_order[screen_desktop])
         goto done_cycle;
@@ -405,10 +605,8 @@ void focus_directional_cycle(ObDirection dir,
         
     if (ft) {
         if (ft != focus_cycle_target) {/* prevents flicker */
         
     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;
             focus_cycle_target = ft;
-            frame_adjust_focus(focus_cycle_target->frame, TRUE);
+            focus_cycle_draw_indicator();
         }
     }
     if (focus_cycle_target) {
         }
     }
     if (focus_cycle_target) {
@@ -425,6 +623,7 @@ done_cycle:
     first = NULL;
     focus_cycle_target = NULL;
 
     first = NULL;
     focus_cycle_target = NULL;
 
+    focus_cycle_draw_indicator();
     popup_cycle(ft, FALSE);
 
     return;
     popup_cycle(ft, FALSE);
 
     return;
This page took 0.033901 seconds and 4 git commands to generate.