X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=af239d23887f2f957d75d1772cb584e44a9ce69f;hb=e043faec9e073c8f5599a72b4f8b87160a3fbaa0;hp=5175cbfb70479ce899d511a1b2d9d0579afa95bc;hpb=9752670920352bdd721d9958370edc569481d9e6;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index 5175cbfb..af239d23 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -38,6 +38,7 @@ #include "mainloop.h" #include "framerender.h" #include "focus.h" +#include "focus_cycle.h" #include "moveresize.h" #include "group.h" #include "stacking.h" @@ -264,15 +265,6 @@ static void event_hack_mods(XEvent *e) break; case MotionNotify: e->xmotion.state = modkeys_only_modifier_masks(e->xmotion.state); - /* compress events */ - { - XEvent ce; - while (XCheckTypedWindowEvent(ob_display, e->xmotion.window, - e->type, &ce)) { - e->xmotion.x_root = ce.xmotion.x_root; - e->xmotion.y_root = ce.xmotion.y_root; - } - } break; } } @@ -771,7 +763,8 @@ static void event_handle_client(ObClient *client, XEvent *e) { /* use where the press occured */ con = frame_context(client, e->xbutton.window, px, py); - con = mouse_button_frame_context(con, e->xbutton.button); + con = mouse_button_frame_context(con, e->xbutton.button, + e->xbutton.state); if (e->type == ButtonRelease && e->xbutton.button == pb) pb = 0, px = py = -1; @@ -808,6 +801,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 || @@ -859,6 +854,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); @@ -973,14 +984,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); @@ -988,8 +996,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; } @@ -1009,8 +1022,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; + /* if a stacking change moves the window without resizing */ + move = TRUE; } /* don't allow clients to move shaded windows (fvwm does this) */ @@ -1022,7 +1035,7 @@ static void event_handle_client(ObClient *client, XEvent *e) /* if the client tried to move and we aren't letting it then a synthetic event is needed */ - config = TRUE; + move = TRUE; } if (e->xconfigurerequest.value_mask & CWX || @@ -1030,25 +1043,31 @@ 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) + if (e->xconfigurerequest.value_mask & CWX) { x = e->xconfigurerequest.x; - if (e->xconfigurerequest.value_mask & CWY) + move = TRUE; + } + if (e->xconfigurerequest.value_mask & CWY) { y = e->xconfigurerequest.y; - if (e->xconfigurerequest.value_mask & CWWidth) + move = TRUE; + } + if (e->xconfigurerequest.value_mask & CWWidth) { w = e->xconfigurerequest.width; - if (e->xconfigurerequest.value_mask & CWHeight) + resize = TRUE; + } + if (e->xconfigurerequest.value_mask & CWHeight) { h = e->xconfigurerequest.height; - - /* if a new position or size is requested, then a configure is - needed */ - config = TRUE; + resize = TRUE; + } } - 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 @@ -1057,7 +1076,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 && @@ -1072,11 +1092,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(); @@ -1186,11 +1218,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)); @@ -1273,8 +1310,8 @@ static void event_handle_client(ObClient *client, XEvent *e) } else { ObClient *sibling = NULL; if (e->xclient.data.l[1]) { - ObWindow *win = g_hash_table_lookup(window_map, - &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) { @@ -1481,8 +1518,11 @@ static gboolean event_handle_menu_keyboard(XEvent *ev) ret = FALSE; else if (keycode == ob_keycode(OB_KEY_ESCAPE) && state == 0) { - /* Escape closes the active menu */ - menu_frame_hide(frame); + /* Escape goes to the parent menu or closes the last one */ + if (frame->parent) + menu_frame_select(frame, NULL, TRUE); + else + menu_frame_hide_all(); } else if (keycode == ob_keycode(OB_KEY_RETURN) && (state == 0 || @@ -1606,6 +1646,10 @@ static gboolean event_handle_menu(XEvent *ev) } break; case LeaveNotify: + /*ignore leaves when we're already in the window */ + if (ev->xcrossing.detail == NotifyInferior) + break; + if ((e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window)) && (f = find_active_menu()) && f->selected == e && e->entry->type != OB_MENU_ENTRY_TYPE_SUBMENU)