Allow clients to place themselves up to 99% offscreen.
[mikachu/openbox.git] / openbox / client.c
index 88b08f9..07ffbbf 100644 (file)
@@ -218,7 +218,7 @@ void client_manage(Window window, ObPrompt *prompt)
     Time launch_time;
     guint32 user_time;
     gboolean obplaced;
-    gulong ignore_start;
+    gulong ignore_start = FALSE;
 
     ob_debug("Managing window: 0x%lx", window);
 
@@ -1169,14 +1169,14 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
            only limiting the application.
         */
         if (client_normal(self)) {
-            if (!self->strut.right && *x + fw/10 >= a->x + a->width - 1)
-                *x = a->x + a->width - fw/10;
-            if (!self->strut.bottom && *y + fh/10 >= a->y + a->height - 1)
-                *y = a->y + a->height - fh/10;
-            if (!self->strut.left && *x + fw*9/10 - 1 < a->x)
-                *x = a->x - fw*9/10;
-            if (!self->strut.top && *y + fh*9/10 - 1 < a->y)
-                *y = a->y - fh*9/10;
+            if (!self->strut.right && *x + fw/100 >= a->x + a->width - 1)
+                *x = a->x + a->width - fw/100;
+            if (!self->strut.bottom && *y + fh/100 >= a->y + a->height - 1)
+                *y = a->y + a->height - fh/100;
+            if (!self->strut.left && *x + fw*99/100 - 1 < a->x)
+                *x = a->x - fw*99/100;
+            if (!self->strut.top && *y + fh*99/100 - 1 < a->y)
+                *y = a->y - fh*99/100;
         }
 
         /* This here doesn't let windows even a pixel outside the
@@ -2309,6 +2309,10 @@ void client_update_icons(ObClient *self)
     if (!self->icon_set && !self->parents) {
         RrPixel32 *icon = ob_rr_theme->def_win_icon;
         gulong *ldata; /* use a long here to satisfy OBT_PROP_SETA32 */
+        gint32 r,g,b;
+        r = g_random_int_range(0,255);
+        g = g_random_int_range(0,255);
+        b = g_random_int_range(0,255);
 
         w = ob_rr_theme->def_win_icon_w;
         h = ob_rr_theme->def_win_icon_h;
@@ -2317,9 +2321,9 @@ void client_update_icons(ObClient *self)
         ldata[1] = h;
         for (i = 0; i < w*h; ++i)
             ldata[i+2] = (((icon[i] >> RrDefaultAlphaOffset) & 0xff) << 24) +
-                (((icon[i] >> RrDefaultRedOffset) & 0xff) << 16) +
-                (((icon[i] >> RrDefaultGreenOffset) & 0xff) << 8) +
-                (((icon[i] >> RrDefaultBlueOffset) & 0xff) << 0);
+                ((((icon[i] >> RrDefaultRedOffset) & 0xff)*r/255) << 16) +
+                ((((icon[i] >> RrDefaultGreenOffset) & 0xff)*g/255) << 8) +
+                ((((icon[i] >> RrDefaultBlueOffset) & 0xff)*b/255) << 0);
         OBT_PROP_SETA32(self->window, NET_WM_ICON, CARDINAL, ldata, w*h+2);
         g_free(ldata);
     } else if (self->frame)
@@ -2734,7 +2738,7 @@ gboolean client_should_show(ObClient *self)
 {
     if (self->iconic)
         return FALSE;
-    if (client_normal(self) && screen_showing_desktop)
+    if (client_normal(self) && screen_showing_desktop())
         return FALSE;
     if (self->desktop == screen_desktop || self->desktop == DESKTOP_ALL)
         return TRUE;
@@ -2824,7 +2828,7 @@ gboolean client_occupies_space(ObClient *self)
 
 gboolean client_mouse_focusable(ObClient *self)
 {
-    return !(self->type == OB_CLIENT_TYPE_MENU ||
+    return !(/*self->type == OB_CLIENT_TYPE_MENU ||*/
              self->type == OB_CLIENT_TYPE_TOOLBAR ||
              self->type == OB_CLIENT_TYPE_SPLASH ||
              self->type == OB_CLIENT_TYPE_DOCK);
@@ -4022,6 +4026,13 @@ gboolean client_focus(ObClient *self)
 {
     if (!client_validate(self)) return FALSE;
 
+    {
+        XkbStateRec state;
+        XkbGetState(obt_display, XkbUseCoreKbd, &state);
+        if (state.locked_mods & 128)
+            return FALSE;
+    }
+
     /* we might not focus this window, so if we have modal children which would
        be focused instead, bring them to this desktop */
     client_bring_modal_windows(self);
@@ -4080,7 +4091,7 @@ gboolean client_focus(ObClient *self)
 static void client_present(ObClient *self, gboolean here, gboolean raise,
                            gboolean unshade)
 {
-    if (client_normal(self) && screen_showing_desktop)
+    if (client_normal(self) && screen_showing_desktop())
         screen_show_desktop(FALSE, self);
     if (self->iconic)
         client_iconify(self, FALSE, here, FALSE);
@@ -4535,8 +4546,9 @@ void client_find_move_directional(ObClient *self, ObDirection dir,
     frame_frame_gravity(self->frame, x, y);
 }
 
-void client_find_resize_directional(ObClient *self, ObDirection side,
-                                    gboolean grow,
+void client_find_resize_directional(ObClient *self,
+                                    ObDirection side,
+                                    ObClientDirectionalResizeType resize_type,
                                     gint *x, gint *y, gint *w, gint *h)
 {
     gint head;
@@ -4544,31 +4556,84 @@ void client_find_resize_directional(ObClient *self, ObDirection side,
     gboolean near;
     ObDirection dir;
 
+    gboolean grow;
+    switch (resize_type) {
+    case CLIENT_RESIZE_GROW:
+        grow = TRUE;
+        break;
+    case CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE:
+        grow = TRUE;
+        break;
+    case CLIENT_RESIZE_SHRINK:
+        grow = FALSE;
+        break;
+    }
+
     switch (side) {
     case OB_DIRECTION_EAST:
-        head = RECT_RIGHT(self->frame->area) +
-            (self->size_inc.width - 1) * (grow ? 1 : 0);
+        head = RECT_RIGHT(self->frame->area);
+        switch (resize_type) {
+        case CLIENT_RESIZE_GROW:
+            head += self->size_inc.width - 1;
+            break;
+        case CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE:
+            head -= 1;
+            break;
+        case CLIENT_RESIZE_SHRINK:
+            break;
+        }
+
         e_start = RECT_TOP(self->frame->area);
         e_size = self->frame->area.height;
         dir = grow ? OB_DIRECTION_EAST : OB_DIRECTION_WEST;
         break;
     case OB_DIRECTION_WEST:
-        head = RECT_LEFT(self->frame->area) -
-            (self->size_inc.width - 1) * (grow ? 1 : 0);
+        head = RECT_LEFT(self->frame->area);
+        switch (resize_type) {
+        case CLIENT_RESIZE_GROW:
+            head -= self->size_inc.width - 1;
+            break;
+        case CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE:
+            head += 1;
+            break;
+        case CLIENT_RESIZE_SHRINK:
+            break;
+        }
+
         e_start = RECT_TOP(self->frame->area);
         e_size = self->frame->area.height;
         dir = grow ? OB_DIRECTION_WEST : OB_DIRECTION_EAST;
         break;
     case OB_DIRECTION_NORTH:
-        head = RECT_TOP(self->frame->area) -
-            (self->size_inc.height - 1) * (grow ? 1 : 0);
+        head = RECT_TOP(self->frame->area);
+        switch (resize_type) {
+        case CLIENT_RESIZE_GROW:
+            head -= self->size_inc.height - 1;
+            break;
+        case CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE:
+            head += 1;
+            break;
+        case CLIENT_RESIZE_SHRINK:
+            break;
+        }
+
         e_start = RECT_LEFT(self->frame->area);
         e_size = self->frame->area.width;
         dir = grow ? OB_DIRECTION_NORTH : OB_DIRECTION_SOUTH;
         break;
     case OB_DIRECTION_SOUTH:
-        head = RECT_BOTTOM(self->frame->area) +
-            (self->size_inc.height - 1) * (grow ? 1 : 0);
+        head = RECT_BOTTOM(self->frame->area);
+        switch (resize_type) {
+        case CLIENT_RESIZE_GROW:
+            head += self->size_inc.height - 1;
+            break;
+        case CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE:
+            head -= 1;
+            break;
+        case CLIENT_RESIZE_SHRINK:
+            break;
+        }
+
         e_start = RECT_LEFT(self->frame->area);
         e_size = self->frame->area.width;
         dir = grow ? OB_DIRECTION_SOUTH : OB_DIRECTION_NORTH;
@@ -4607,7 +4672,7 @@ void client_find_resize_directional(ObClient *self, ObDirection side,
         if (grow == near) --e;
         delta = e - RECT_BOTTOM(self->frame->area);
         *h += delta;
-        break;
+       break;
     default:
         g_assert_not_reached();
     }