Apply combined shape mask correctly
[mikachu/openbox.git] / openbox / frame.c
index 24d3eb5..5b695f7 100644 (file)
@@ -28,6 +28,7 @@
 #include "focus_cycle_indicator.h"
 #include "moveresize.h"
 #include "screen.h"
+#include "edges.h"
 #include "obrender/theme.h"
 #include "obt/display.h"
 #include "obt/xqueue.h"
@@ -318,7 +319,7 @@ void frame_adjust_shape_kind(ObFrame *self, int kind)
         }
 
         XShapeCombineRectangles(obt_display, self->window,
-                                ShapeBounding, 0, 0, xrect, num,
+                                kind, 0, 0, xrect, num,
                                 ShapeUnion, Unsorted);
     }
 }
@@ -387,11 +388,10 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
         if (self->decorations & OB_FRAME_DECOR_TITLEBAR)
             self->size.top += ob_rr_theme->title_height + self->bwidth;
         else if (self->max_horz && self->max_vert) {
-            /* A maximized and undecorated window needs a small border on the
+            /* A maximized and undecorated window needs a border on the
                top of the window to let the user still undecorate/unmaximize the
                window via the client menu. */
-            /* XXX This size should probably be a theme option. */
-            self->size.top += 1;
+            self->size.top += self->bwidth;
         }
 
         if (self->decorations & OB_FRAME_DECOR_HANDLE &&
@@ -1387,6 +1387,22 @@ ObFrameContext frame_context_from_string(const gchar *name)
         return OB_FRAME_CONTEXT_MOVE_RESIZE;
     else if (!g_ascii_strcasecmp("Dock", name))
         return OB_FRAME_CONTEXT_DOCK;
+    else if (!g_ascii_strcasecmp("ScreenTop", name))
+        return OB_FRAME_CONTEXT_EDGE_TOP;
+    else if (!g_ascii_strcasecmp("ScreenTopRight", name))
+        return OB_FRAME_CONTEXT_EDGE_TOPRIGHT;
+    else if (!g_ascii_strcasecmp("ScreenRight", name))
+        return OB_FRAME_CONTEXT_EDGE_RIGHT;
+    else if (!g_ascii_strcasecmp("ScreenBottomRight", name))
+        return OB_FRAME_CONTEXT_EDGE_BOTTOMRIGHT;
+    else if (!g_ascii_strcasecmp("ScreenBottom", name))
+        return OB_FRAME_CONTEXT_EDGE_BOTTOM;
+    else if (!g_ascii_strcasecmp("ScreenBottomLeft", name))
+        return OB_FRAME_CONTEXT_EDGE_BOTTOMLEFT;
+    else if (!g_ascii_strcasecmp("ScreenLeft", name))
+        return OB_FRAME_CONTEXT_EDGE_LEFT;
+    else if (!g_ascii_strcasecmp("ScreenTopLeft", name))
+        return OB_FRAME_CONTEXT_EDGE_TOPLEFT;
 
     return OB_FRAME_CONTEXT_NONE;
 }
@@ -1398,12 +1414,14 @@ ObFrameContext frame_context(ObClient *client, Window win, gint x, gint y)
 
     if (moveresize_in_progress)
         return OB_FRAME_CONTEXT_MOVE_RESIZE;
-
     if (win == obt_root(ob_screen))
         return OB_FRAME_CONTEXT_ROOT;
     if ((obwin = window_find(win))) {
         if (WINDOW_IS_DOCK(obwin)) {
           return OB_FRAME_CONTEXT_DOCK;
+        } else if (WINDOW_IS_EDGE(obwin)) {
+          ObEdge *edge = (ObEdge *)obwin;
+          return OB_FRAME_CONTEXT_EDGE_TOP + edge->location;
         }
     }
     if (client == NULL) return OB_FRAME_CONTEXT_NONE;
@@ -1665,8 +1683,7 @@ static void flash_done(gpointer data)
 {
     ObFrame *self = data;
 
-    if (self->focused != self->flash_on)
-        frame_adjust_focus(self, self->focused);
+    self->flash_timer = 0;
 }
 
 static gboolean flash_timeout(gpointer data)
@@ -1680,8 +1697,12 @@ static gboolean flash_timeout(gpointer data)
          now.tv_usec >= self->flash_end.tv_usec))
         self->flashing = FALSE;
 
-    if (!self->flashing)
+    if (!self->flashing) {
+        if (self->focused != self->flash_on)
+            frame_adjust_focus(self, self->focused);
+
         return FALSE; /* we are done */
+    }
 
     self->flash_on = !self->flash_on;
     if (!self->focused) {
@@ -1788,14 +1809,12 @@ static gboolean frame_animate_iconify(gpointer p)
     XMoveResizeWindow(obt_display, self->window, x, y, w, h);
     XFlush(obt_display);
 
-    if (time == 0)
-        frame_end_iconify_animation(self);
-
     return time > 0; /* repeat until we're out of time */
 }
 
-void frame_end_iconify_animation(ObFrame *self)
+void frame_end_iconify_animation(gpointer data)
 {
+    ObFrame *self = data;
     /* see if there is an animation going */
     if (self->iconify_animation_going == 0) return;
 
@@ -1812,6 +1831,7 @@ void frame_end_iconify_animation(ObFrame *self)
 
     /* we're not animating any more ! */
     self->iconify_animation_going = 0;
+    self->iconify_animation_timer = 0;
 
     XMoveResizeWindow(obt_display, self->window,
                       self->area.x, self->area.y,
@@ -1862,7 +1882,8 @@ void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying)
         self->iconify_animation_timer =
             g_timeout_add_full(G_PRIORITY_DEFAULT,
                                FRAME_ANIMATE_ICONIFY_STEP_TIME,
-                               frame_animate_iconify, self, NULL);
+                               frame_animate_iconify, self,
+                               frame_end_iconify_animation);
                                
 
         /* do the first step */