]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
yay! gravity finally works right!
[chaz/openbox] / openbox / event.c
index bf2fd932cf1f68e2ab90888cb627743641560b73..c19f70175d1567323b8a28a906cd70e476f3b094 100644 (file)
@@ -679,7 +679,7 @@ static void event_handle_root(XEvent *e)
             }
         } else if (msgtype == prop_atoms.net_number_of_desktops) {
             guint d = e->xclient.data.l[0];
-            if (d > 0)
+            if (d > 0 && d <= 1000)
                 screen_set_num_desktops(d);
         } else if (msgtype == prop_atoms.net_showing_desktop) {
             screen_show_desktop(e->xclient.data.l[0] != 0, NULL);
@@ -810,6 +810,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
                             e->xmotion.x, e->xmotion.y);
         switch (con) {
         case OB_FRAME_CONTEXT_TITLEBAR:
+        case OB_FRAME_CONTEXT_TLCORNER:
+        case OB_FRAME_CONTEXT_TRCORNER:
             /* we've left the button area inside the titlebar */
             if (client->frame->max_hover || client->frame->desk_hover ||
                 client->frame->shade_hover || client->frame->iconify_hover ||
@@ -861,6 +863,22 @@ static void event_handle_client(ObClient *client, XEvent *e)
         con = frame_context(client, e->xcrossing.window,
                             e->xcrossing.x, e->xcrossing.y);
         switch (con) {
+        case OB_FRAME_CONTEXT_TITLEBAR:
+        case OB_FRAME_CONTEXT_TLCORNER:
+        case OB_FRAME_CONTEXT_TRCORNER:
+            /* we've left the button area inside the titlebar */
+            if (client->frame->max_hover || client->frame->desk_hover ||
+                client->frame->shade_hover || client->frame->iconify_hover ||
+                client->frame->close_hover)
+            {
+                client->frame->max_hover = FALSE;
+                client->frame->desk_hover = FALSE;
+                client->frame->shade_hover = FALSE;
+                client->frame->iconify_hover = FALSE;
+                client->frame->close_hover = FALSE;
+                frame_adjust_state(client->frame);
+            }
+            break;
         case OB_FRAME_CONTEXT_MAXIMIZE:
             client->frame->max_hover = FALSE;
             frame_adjust_state(client->frame);
@@ -975,14 +993,11 @@ static void event_handle_client(ObClient *client, XEvent *e)
         */
 
         gint x, y, w, h;
+        gboolean move = FALSE;
+        gboolean resize = FALSE;
 
-        /* if nothing is changed, then a configurenotify is needed */
-        gboolean config = TRUE;
-
-        x = client->area.x;
-        y = client->area.y;
-        w = client->area.width;
-        h = client->area.height;
+        /* get the current area */
+        RECT_TO_DIMS(client->area, x, y, w, h);
 
         ob_debug("ConfigureRequest desktop %d wmstate %d visibile %d\n",
                  screen_desktop, client->wmstate, client->frame->visible);
@@ -990,8 +1005,13 @@ static void event_handle_client(ObClient *client, XEvent *e)
         if (e->xconfigurerequest.value_mask & CWBorderWidth)
             if (client->border_width != e->xconfigurerequest.border_width) {
                 client->border_width = e->xconfigurerequest.border_width;
-                /* if only the border width is changing, then it's not needed*/
-                config = FALSE;
+
+                /* if the border width is changing then that is the same
+                   as requesting a resize, but we don't actually change
+                   the client's border, so it will change their root
+                   coordiantes (since they include the border width) and
+                   we need to a notify then */
+                move = TRUE;
             }
 
 
@@ -1011,20 +1031,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
             stacking_restack_request(client, sibling,
                                      e->xconfigurerequest.detail, TRUE);
 
-            /* if a stacking change is requested then it is needed */
-            config = TRUE;
-        }
-
-        /* don't allow clients to move shaded windows (fvwm does this) */
-        if (client->shaded && (e->xconfigurerequest.value_mask & CWX ||
-                               e->xconfigurerequest.value_mask & CWY))
-        {
-            e->xconfigurerequest.value_mask &= ~CWX;
-            e->xconfigurerequest.value_mask &= ~CWY;
-
-            /* if the client tried to move and we aren't letting it then a
-               synthetic event is needed */
-            config = TRUE;
+            /* if a stacking change moves the window without resizing */
+            move = TRUE;
         }
 
         if (e->xconfigurerequest.value_mask & CWX ||
@@ -1032,25 +1040,48 @@ static void event_handle_client(ObClient *client, XEvent *e)
             e->xconfigurerequest.value_mask & CWWidth ||
             e->xconfigurerequest.value_mask & CWHeight)
         {
-            if (e->xconfigurerequest.value_mask & CWX)
-                x = e->xconfigurerequest.x;
-            if (e->xconfigurerequest.value_mask & CWY)
-                y = e->xconfigurerequest.y;
-            if (e->xconfigurerequest.value_mask & CWWidth)
+            if (e->xconfigurerequest.value_mask & CWX) {
+                /* don't allow clients to move shaded windows (fvwm does this)
+                 */
+                if (!client->shaded)
+                    x = e->xconfigurerequest.x;
+                move = TRUE;
+            }
+            if (e->xconfigurerequest.value_mask & CWY) {
+                /* don't allow clients to move shaded windows (fvwm does this)
+                 */
+                if (!client->shaded)
+                    y = e->xconfigurerequest.y;
+                move = TRUE;
+            }
+
+            if (e->xconfigurerequest.value_mask & CWWidth) {
                 w = e->xconfigurerequest.width;
-            if (e->xconfigurerequest.value_mask & CWHeight)
+                resize = TRUE;
+
+                /* if x was not given, then use gravity to figure out the new
+                   x.  the reference point should not be moved */
+                if (!(e->xconfigurerequest.value_mask & CWX))
+                    client_gravity_resize_w(client, &x, client->area.width, w);
+            }
+            if (e->xconfigurerequest.value_mask & CWHeight) {
                 h = e->xconfigurerequest.height;
+                resize = TRUE;
 
-            /* if a new position or size is requested, then a configure is
-               needed */
-            config = TRUE;
+                /* if y was not given, then use gravity to figure out the new
+                   y.  the reference point should not be moved */
+                if (!(e->xconfigurerequest.value_mask & CWY))
+                    client_gravity_resize_h(client, &y, client->area.height,h);
+            }
         }
 
-        ob_debug("ConfigureRequest x(%d) %d y(%d) %d w(%d) %d h(%d) %d\n",
+        ob_debug("ConfigureRequest x(%d) %d y(%d) %d w(%d) %d h(%d) %d "
+                 "move %d resize %d\n",
                  e->xconfigurerequest.value_mask & CWX, x,
                  e->xconfigurerequest.value_mask & CWY, y,
                  e->xconfigurerequest.value_mask & CWWidth, w,
-                 e->xconfigurerequest.value_mask & CWHeight, h);
+                 e->xconfigurerequest.value_mask & CWHeight, h,
+                 move, resize);
 
         /* check for broken apps moving to their root position
 
@@ -1059,7 +1090,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
            desktop. eg. open amarok window on desktop 1, switch to desktop
            2, click amarok tray icon. it will move by its decoration size.
         */
-        if (x != client->area.x &&
+        if (move && !resize &&
+            x != client->area.x &&
             x == (client->frame->area.x + client->frame->size.left -
                   (gint)client->border_width) &&
             y != client->area.y &&
@@ -1074,11 +1106,23 @@ static void event_handle_client(ObClient *client, XEvent *e)
             /* don't move it */
             x = client->area.x;
             y = client->area.y;
+
+            /* they still requested a move, so don't change whether a
+               notify is sent or not */
         }
 
-        if (config) {
+        if (move || resize) {
+            gint lw,lh;
+
             client_find_onscreen(client, &x, &y, w, h, FALSE);
-            client_configure(client, x, y, w, h, FALSE, TRUE);
+            client_try_configure(client, &x, &y, &w, &h, &lw, &lh, FALSE);
+            /* if they requested something that moves the window, or if
+               the window is actually being changed then configure it and
+               send a configure notify to them */
+            if (move || !RECT_EQUAL_DIMS(client->area, x, y, w, h)) {
+                ob_debug("Doing configure\n");
+                client_configure(client, x, y, w, h, FALSE, TRUE);
+            }
 
             /* ignore enter events caused by these like ob actions do */
             event_ignore_all_queued_enters();
@@ -1188,11 +1232,16 @@ static void event_handle_client(ObClient *client, XEvent *e)
                       (e->xclient.data.l[0] == 1 ? "application" :
                        (e->xclient.data.l[0] == 2 ? "user" : "INVALID"))));
             /* XXX make use of data.l[2] !? */
-            event_curtime = e->xclient.data.l[1];
-            if (event_curtime == 0)
+            if (e->xclient.data.l[0] == 1 || e->xclient.data.l[0] == 2) {
+                event_curtime = e->xclient.data.l[1];
+                if (event_curtime == 0)
+                    ob_debug_type(OB_DEBUG_APP_BUGS,
+                                  "_NET_ACTIVE_WINDOW message for window %s is"
+                                  " missing a timestamp\n", client->title);
+            } else
                 ob_debug_type(OB_DEBUG_APP_BUGS,
                               "_NET_ACTIVE_WINDOW message for window %s is "
-                              "missing a timestamp\n", client->title);
+                              "missing source indication\n");
             client_activate(client, FALSE,
                             (e->xclient.data.l[0] == 0 ||
                              e->xclient.data.l[0] == 2));
@@ -1232,12 +1281,12 @@ static void event_handle_client(ObClient *client, XEvent *e)
                      prop_atoms.net_wm_moveresize_cancel)
                 moveresize_end(TRUE);
         } else if (msgtype == prop_atoms.net_moveresize_window) {
-            gint grav, x, y, w, h;
+            gint ograv, x, y, w, h;
+
+            ograv = client->gravity;
 
             if (e->xclient.data.l[0] & 0xff)
-                grav = e->xclient.data.l[0] & 0xff;
-            else 
-                grav = client->gravity;
+                client->gravity = e->xclient.data.l[0] & 0xff;
 
             if (e->xclient.data.l[0] & 1 << 8)
                 x = e->xclient.data.l[1];
@@ -1247,23 +1296,40 @@ static void event_handle_client(ObClient *client, XEvent *e)
                 y = e->xclient.data.l[2];
             else
                 y = client->area.y;
-            if (e->xclient.data.l[0] & 1 << 10)
+
+            if (e->xclient.data.l[0] & 1 << 10) {
                 w = e->xclient.data.l[3];
+
+                /* if x was not given, then use gravity to figure out the new
+                   x.  the reference point should not be moved */
+                if (!(e->xclient.data.l[0] & 1 << 8))
+                    client_gravity_resize_w(client, &x, client->area.width, w);
+            }
             else
                 w = client->area.width;
-            if (e->xclient.data.l[0] & 1 << 11)
+
+            if (e->xclient.data.l[0] & 1 << 11) {
                 h = e->xclient.data.l[4];
+
+                /* if y was not given, then use gravity to figure out the new
+                   y.  the reference point should not be moved */
+                if (!(e->xclient.data.l[0] & 1 << 9))
+                    client_gravity_resize_h(client, &y, client->area.height,h);
+            }
             else
                 h = client->area.height;
 
-            ob_debug("MOVERESIZE x %d %d y %d %d\n",
+            ob_debug("MOVERESIZE x %d %d y %d %d (gravity %d)\n",
                      e->xclient.data.l[0] & 1 << 8, x,
-                     e->xclient.data.l[0] & 1 << 9, y);
-            client_convert_gravity(client, grav, &x, &y, w, h);
+                     e->xclient.data.l[0] & 1 << 9, y,
+                     client->gravity);
+
             client_find_onscreen(client, &x, &y, w, h, FALSE);
 
             client_configure(client, x, y, w, h, FALSE, TRUE);
 
+            client->gravity = ograv;
+
             /* ignore enter events caused by these like ob actions do */
             event_ignore_all_queued_enters();
         } else if (msgtype == prop_atoms.net_restack_window) {
This page took 0.026051 seconds and 4 git commands to generate.