]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
when un-showing the desktop if a window is getting shown, iconify the others so just...
[chaz/openbox] / openbox / event.c
index babb5197c193ee0316f7403ad303dc2d107b2683..c529f15648e12dcb790b3866fcafe621a17ba272 100644 (file)
@@ -568,6 +568,27 @@ static void event_process(const XEvent *ec, gpointer data)
         event_handle_root(e);
     else if (e->type == MapRequest)
         client_manage(window);
+    else if (e->type == ClientMessage) {
+        /* This is for _NET_WM_REQUEST_FRAME_EXTENTS messages. They come for
+           windows that are not managed yet. */
+        if (e->xclient.message_type == prop_atoms.net_request_frame_extents) {
+            /* Pretend to manage the client, getting information used to
+               determine its decorations */
+            ObClient *c = client_fake_manage(e->xclient.window);
+            gulong vals[4];
+
+            /* set the frame extents on the window */
+            vals[0] = c->frame->size.left;
+            vals[1] = c->frame->size.right;
+            vals[2] = c->frame->size.top;
+            vals[3] = c->frame->size.bottom;
+            PROP_SETA32(e->xclient.window, net_frame_extents,
+                        cardinal, vals, 4);
+
+            /* Free the pretend client */
+            client_fake_unmanage(c);
+        }
+    }
     else if (e->type == ConfigureRequest) {
         /* unhandled configure requests must be used to configure the
            window directly */
@@ -639,7 +660,7 @@ static void event_handle_root(XEvent *e)
             if (d > 0)
                 screen_set_num_desktops(d);
         } else if (msgtype == prop_atoms.net_showing_desktop) {
-            screen_show_desktop(e->xclient.data.l[0] != 0, TRUE);
+            screen_show_desktop(e->xclient.data.l[0] != 0, NULL);
         } else if (msgtype == prop_atoms.openbox_control) {
             if (e->xclient.data.l[0] == 1)
                 ob_reconfigure();
@@ -705,9 +726,17 @@ static void event_handle_client(ObClient *client, XEvent *e)
     XEvent ce;
     Atom msgtype;
     ObFrameContext con;
+    static gint px = -1, py = -1;
+    static guint pb = 0;
      
     switch (e->type) {
     case ButtonPress:
+        /* save where the press occured for the first button pressed */
+        if (!pb) {
+            pb = e->xbutton.button;
+            px = e->xbutton.x;
+            py = e->xbutton.y;
+        }
     case ButtonRelease:
         /* Wheel buttons don't draw because they are an instant click, so it
            is a waste of resources to go drawing it.
@@ -719,8 +748,13 @@ static void event_handle_client(ObClient *client, XEvent *e)
             !keyboard_interactively_grabbed() &&
             !menu_frame_visible)
         {
-            con = frame_context(client, e->xbutton.window);
+            /* use where the press occured */
+            con = frame_context(client, e->xbutton.window, px, py);
             con = mouse_button_frame_context(con, e->xbutton.button);
+
+            if (e->type == ButtonRelease && e->xbutton.button == pb)
+                pb = 0, px = py = -1;
+
             switch (con) {
             case OB_FRAME_CONTEXT_MAXIMIZE:
                 client->frame->max_press = (e->type == ButtonPress);
@@ -748,8 +782,61 @@ static void event_handle_client(ObClient *client, XEvent *e)
             }
         }
         break;
+    case MotionNotify:
+        con = frame_context(client, e->xmotion.window,
+                            e->xmotion.x, e->xmotion.y);
+        switch (con) {
+        case OB_FRAME_CONTEXT_TITLEBAR:
+            /* 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:
+            if (!client->frame->max_hover) {
+                client->frame->max_hover = TRUE;
+                frame_adjust_state(client->frame);
+            }
+            break;
+        case OB_FRAME_CONTEXT_ALLDESKTOPS:
+            if (!client->frame->desk_hover) {
+                client->frame->desk_hover = TRUE;
+                frame_adjust_state(client->frame);
+            }
+            break;
+        case OB_FRAME_CONTEXT_SHADE:
+            if (!client->frame->shade_hover) {
+                client->frame->shade_hover = TRUE;
+                frame_adjust_state(client->frame);
+            }
+            break;
+        case OB_FRAME_CONTEXT_ICONIFY:
+            if (!client->frame->iconify_hover) {
+                client->frame->iconify_hover = TRUE;
+                frame_adjust_state(client->frame);
+            }
+            break;
+        case OB_FRAME_CONTEXT_CLOSE:
+            if (!client->frame->close_hover) {
+                client->frame->close_hover = TRUE;
+                frame_adjust_state(client->frame);
+            }
+            break;
+        default:
+            break;
+        }
+        break;
     case LeaveNotify:
-        con = frame_context(client, e->xcrossing.window);
+        con = frame_context(client, e->xcrossing.window,
+                            e->xcrossing.x, e->xcrossing.y);
         switch (con) {
         case OB_FRAME_CONTEXT_MAXIMIZE:
             client->frame->max_hover = FALSE;
@@ -809,7 +896,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
             nofocus = TRUE;
         }
 
-        con = frame_context(client, e->xcrossing.window);
+        con = frame_context(client, e->xcrossing.window,
+                            e->xcrossing.x, e->xcrossing.y);
         switch (con) {
         case OB_FRAME_CONTEXT_MAXIMIZE:
             client->frame->max_hover = TRUE;
@@ -928,22 +1016,20 @@ static void event_handle_client(ObClient *client, XEvent *e)
         }
 
         if (e->xconfigurerequest.value_mask & CWStackMode) {
-            switch (e->xconfigurerequest.detail) {
-            case Below:
-            case BottomIf:
-                /* Apps are so rude. And this is totally disconnected from
-                   activation/focus. Bleh. */
-                /*client_lower(client);*/
-                break;
-
-            case Above:
-            case TopIf:
-            default:
-                /* Apps are so rude. And this is totally disconnected from
-                   activation/focus. Bleh. */
-                /*client_raise(client);*/
-                break;
+            ObClient *sibling = NULL;
+
+            /* get the sibling */
+            if (e->xconfigurerequest.value_mask & CWSibling) {
+                ObWindow *win;
+                win = g_hash_table_lookup(window_map,
+                                          &e->xconfigurerequest.above);
+                if (WINDOW_IS_CLIENT(win) && WINDOW_AS_CLIENT(win) != client)
+                    sibling = WINDOW_AS_CLIENT(win);
             }
+
+            /* activate it rather than just focus it */
+            stacking_restack_request(client, sibling,
+                                     e->xconfigurerequest.detail, TRUE);
         }
         break;
     case UnmapNotify:
@@ -1120,6 +1206,43 @@ static void event_handle_client(ObClient *client, XEvent *e)
             client_convert_gravity(client, grav, &x, &y, w, h);
             client_find_onscreen(client, &x, &y, w, h, FALSE);
             client_configure(client, x, y, w, h, FALSE, TRUE);
+        } else if (msgtype == prop_atoms.net_restack_window) {
+            if (e->xclient.data.l[0] != 2) {
+                ob_debug_type(OB_DEBUG_APP_BUGS,
+                              "_NET_RESTACK_WINDOW sent for window %s with "
+                              "invalid source indication %ld\n",
+                              client->title, e->xclient.data.l[0]);
+            } else {
+                ObClient *sibling = NULL;
+                if (e->xclient.data.l[1]) {
+                    ObWindow *win = g_hash_table_lookup(window_map,
+                                                        &e->xclient.data.l[1]);
+                    if (WINDOW_IS_CLIENT(win) &&
+                        WINDOW_AS_CLIENT(win) != client)
+                    {
+                        sibling = WINDOW_AS_CLIENT(win);
+                    }
+                    if (sibling == NULL)
+                        ob_debug_type(OB_DEBUG_APP_BUGS,
+                                      "_NET_RESTACK_WINDOW sent for window %s "
+                                      "with invalid sibling 0x%x\n",
+                                 client->title, e->xclient.data.l[1]);
+                }
+                if (e->xclient.data.l[2] == Below ||
+                    e->xclient.data.l[2] == BottomIf ||
+                    e->xclient.data.l[2] == Above ||
+                    e->xclient.data.l[2] == TopIf ||
+                    e->xclient.data.l[2] == Opposite)
+                {
+                    /* just raise, don't activate */
+                    stacking_restack_request(client, sibling,
+                                             e->xclient.data.l[2], FALSE);
+                } else
+                    ob_debug_type(OB_DEBUG_APP_BUGS,
+                                  "_NET_RESTACK_WINDOW sent for window %s "
+                                  "with invalid detail %d\n",
+                                  client->title, e->xclient.data.l[2]);
+            }
         }
         break;
     case PropertyNotify:
@@ -1167,7 +1290,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
             client_update_wmhints(client);
         } else if (msgtype == XA_WM_TRANSIENT_FOR) {
             client_update_transient_for(client);
-            client_get_type(client);
+            client_get_type_and_transientness(client);
             /* type may have changed, so update the layer */
             client_calc_layer(client);
             client_setup_decor_and_functions(client);
@@ -1510,7 +1633,7 @@ static gboolean focus_delay_func(gpointer data)
     event_curtime = d->time;
     if (focus_client != d->client) {
         if (client_focus(d->client) && config_focus_raise)
-            client_raise(d->client);
+            stacking_raise(CLIENT_AS_WINDOW(d->client));
     }
     event_curtime = old;
     return FALSE; /* no repeat */
This page took 0.026721 seconds and 4 git commands to generate.