X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=0c594d6bcba135d02d133ee4806ced76e6d6f224;hb=ae4bb6bcb25e3e8b2405b38baebc1859b8135454;hp=fe06935d97898425d4342c4772d79b811c3e0808;hpb=7f262bc2a0733a77ae5a30752aecdcf4ba35f223;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index fe06935d..0c594d6b 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -729,9 +729,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. @@ -743,8 +751,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); @@ -772,8 +785,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; @@ -833,7 +899,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; @@ -952,20 +1019,55 @@ static void event_handle_client(ObClient *client, XEvent *e) } if (e->xconfigurerequest.value_mask & CWStackMode) { + 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)) + sibling = WINDOW_AS_CLIENT(win); + } + switch (e->xconfigurerequest.detail) { case Below: + ob_debug("ConfigureRequest Below for client %s sibling %s\n", + client->title, sibling ? sibling->title : "(all)"); + /* just lower it */ + stacking_lower(CLIENT_AS_WINDOW(client)); + break; case BottomIf: - /* Apps are so rude. And this is totally disconnected from - activation/focus. Bleh. */ - /*client_lower(client);*/ + ob_debug("ConfigureRequest BottomIf for client %s sibling " + "%s\n", + client->title, sibling ? sibling->title : "(all)"); + /* if this client occludes sibling (or anything if NULL), then + lower it to the bottom */ + if (stacking_occluded(sibling, client)) + stacking_lower(CLIENT_AS_WINDOW(client)); break; - case Above: + ob_debug("ConfigureRequest Above for client %s sibling %s\n", + client->title, sibling ? sibling->title : "(all)"); + /* activate it rather than just focus it */ + client_activate(client, FALSE, FALSE); + break; case TopIf: + ob_debug("ConfigureRequest TopIf for client %s sibling %s\n", + client->title, sibling ? sibling->title : "(all)"); + if (stacking_occluded(client, sibling)) + /* activate it rather than just focus it */ + client_activate(client, FALSE, FALSE); + case Opposite: + ob_debug("ConfigureRequest Opposite for client %s sibling " + "%s\n", + client->title, sibling ? sibling->title : "(all)"); + if (stacking_occluded(client, sibling)) + /* activate it rather than just focus it */ + client_activate(client, FALSE, FALSE); + else if (stacking_occluded(sibling, client)) + stacking_lower(CLIENT_AS_WINDOW(client)); default: - /* Apps are so rude. And this is totally disconnected from - activation/focus. Bleh. */ - /*client_raise(client);*/ break; } } @@ -1534,7 +1636,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 */