X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=8c64052275ece34e21983f25d764f5adde59858a;hb=a09984bbc076bc37b11058237f51fa15114129e2;hp=ce5be14d0c276d1db03ddb3a6ce5a9f5264b65ca;hpb=f37a9190959279d0f3c1cd7e62099e74930d36d2;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index ce5be14d..8c640522 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -8,6 +8,8 @@ #include "screen.h" #include "frame.h" #include "menu.h" +#include "keyboard.h" +#include "mouse.h" #include "framerender.h" #include "focus.h" #include "moveresize.h" @@ -223,32 +225,38 @@ static Window event_get_window(XEvent *e) static void event_set_lasttime(XEvent *e) { + Time t = 0; + /* grab the lasttime and hack up the state */ switch (e->type) { case ButtonPress: case ButtonRelease: - event_lasttime = e->xbutton.time; + t = e->xbutton.time; break; case KeyPress: - event_lasttime = e->xkey.time; + t = e->xkey.time; break; case KeyRelease: - event_lasttime = e->xkey.time; + t = e->xkey.time; break; case MotionNotify: - event_lasttime = e->xmotion.time; + t = e->xmotion.time; break; case PropertyNotify: - event_lasttime = e->xproperty.time; + t = e->xproperty.time; break; case EnterNotify: case LeaveNotify: - event_lasttime = e->xcrossing.time; + t = e->xcrossing.time; break; default: - event_lasttime = CurrentTime; + /* if more event types are anticipated, get their timestamp + explicitly */ break; } + + if (t > event_lasttime) + event_lasttime = t; } #define STRIP_MODS(s) \ @@ -535,13 +543,23 @@ static void event_process(XEvent *e) } /* user input (action-bound) events */ - /* if (e->type == ButtonPress || e->type == ButtonRelease || - e->type == MotionNotify) - mouse_event(e, client); - else if (e->type == KeyPress || e->type == KeyRelease) - ; - */ + e->type == MotionNotify || e->type == KeyPress || + e->type == KeyRelease) + { + ObFrameContext context; + + context = frame_context(client, e->xany.window); + + if (!keyboard_process_interactive_grab(e, &client, &context)) { + + if (e->type == ButtonPress || e->type == ButtonRelease || + e->type == MotionNotify) + mouse_event(client, context, e); + else if (e->type == KeyPress) + keyboard_event(client, e); + } + } /* dispatch the event to registered handlers */ dispatch_x(e, client); @@ -600,8 +618,12 @@ static void event_handle_client(ObClient *client, XEvent *e) XEvent ce; Atom msgtype; int i=0; + ObFrameContext con; switch (e->type) { + case VisibilityNotify: + client->frame->obscured = e->xvisibility.state != VisibilityUnobscured; + break; case ButtonPress: case ButtonRelease: /* Wheel buttons don't draw because they are an instant click, so it @@ -657,23 +679,77 @@ static void event_handle_client(ObClient *client, XEvent *e) client_iconify(client, TRUE, TRUE); frame_adjust_focus(client->frame, FALSE); break; + case LeaveNotify: + con = frame_context(client, e->xcrossing.window); + switch (con) { + case OB_FRAME_CONTEXT_MAXIMIZE: + client->frame->max_hover = FALSE; + frame_adjust_state(client->frame); + break; + case OB_FRAME_CONTEXT_ALLDESKTOPS: + client->frame->desk_hover = FALSE; + frame_adjust_state(client->frame); + break; + case OB_FRAME_CONTEXT_SHADE: + client->frame->shade_hover = FALSE; + frame_adjust_state(client->frame); + break; + case OB_FRAME_CONTEXT_ICONIFY: + client->frame->iconify_hover = FALSE; + frame_adjust_state(client->frame); + break; + case OB_FRAME_CONTEXT_CLOSE: + client->frame->close_hover = FALSE; + frame_adjust_state(client->frame); + break; + default: + break; + } + break; case EnterNotify: - if (client_normal(client)) { - if (ob_state() == OB_STATE_STARTING) { - /* move it to the top of the focus order */ - guint desktop = client->desktop; - if (desktop == DESKTOP_ALL) desktop = screen_desktop; - focus_order[desktop] = g_list_remove(focus_order[desktop], - client); - focus_order[desktop] = g_list_prepend(focus_order[desktop], - client); - } else if (config_focus_follow) { + con = frame_context(client, e->xcrossing.window); + switch (con) { + case OB_FRAME_CONTEXT_MAXIMIZE: + client->frame->max_hover = TRUE; + frame_adjust_state(client->frame); + break; + case OB_FRAME_CONTEXT_ALLDESKTOPS: + client->frame->desk_hover = TRUE; + frame_adjust_state(client->frame); + break; + case OB_FRAME_CONTEXT_SHADE: + client->frame->shade_hover = TRUE; + frame_adjust_state(client->frame); + break; + case OB_FRAME_CONTEXT_ICONIFY: + client->frame->iconify_hover = TRUE; + frame_adjust_state(client->frame); + break; + case OB_FRAME_CONTEXT_CLOSE: + client->frame->close_hover = TRUE; + frame_adjust_state(client->frame); + break; + case OB_FRAME_CONTEXT_FRAME: + if (client_normal(client)) { + if (ob_state() == OB_STATE_STARTING) { + /* move it to the top of the focus order */ + guint desktop = client->desktop; + if (desktop == DESKTOP_ALL) desktop = screen_desktop; + focus_order[desktop] = g_list_remove(focus_order[desktop], + client); + focus_order[desktop] = g_list_prepend(focus_order[desktop], + client); + } else if (config_focus_follow) { #ifdef DEBUG_FOCUS - ob_debug("EnterNotify on %lx, focusing window\n", - client->window); + ob_debug("EnterNotify on %lx, focusing window\n", + client->window); #endif - client_focus(client); + client_focus(client); + } } + break; + default: + break; } break; case ConfigureRequest: @@ -703,15 +779,16 @@ static void event_handle_client(ObClient *client, XEvent *e) /* if we are iconic (or shaded (fvwm does this)) ignore the event */ if (client->iconic || client->shaded) return; - if (e->xconfigurerequest.value_mask & CWBorderWidth) - client->border_width = e->xconfigurerequest.border_width; - /* resize, then move, as specified in the EWMH section 7.7 */ if (e->xconfigurerequest.value_mask & (CWWidth | CWHeight | - CWX | CWY)) { + CWX | CWY | + CWBorderWidth)) { int x, y, w, h; ObCorner corner; - + + if (e->xconfigurerequest.value_mask & CWBorderWidth) + client->border_width = e->xconfigurerequest.border_width; + x = (e->xconfigurerequest.value_mask & CWX) ? e->xconfigurerequest.x : client->area.x; y = (e->xconfigurerequest.value_mask & CWY) ? @@ -720,6 +797,20 @@ static void event_handle_client(ObClient *client, XEvent *e) e->xconfigurerequest.width : client->area.width; h = (e->xconfigurerequest.value_mask & CWHeight) ? e->xconfigurerequest.height : client->area.height; + + { + int newx = x; + int newy = y; + int fw = w + + client->frame->size.left + client->frame->size.right; + int fh = h + + client->frame->size.top + client->frame->size.bottom; + client_find_onscreen(client, &newx, &newy, fw, fh, TRUE); + if (e->xconfigurerequest.value_mask & CWX) + x = newx; + if (e->xconfigurerequest.value_mask & CWY) + y = newy; + } switch (client->gravity) { case NorthEastGravity: @@ -737,7 +828,8 @@ static void event_handle_client(ObClient *client, XEvent *e) corner = OB_CORNER_TOPLEFT; } - client_configure(client, corner, x, y, w, h, FALSE, TRUE); + client_configure_full(client, corner, x, y, w, h, FALSE, TRUE, + TRUE); } if (e->xconfigurerequest.value_mask & CWStackMode) { @@ -850,7 +942,7 @@ static void event_handle_client(ObClient *client, XEvent *e) client_close(client); } else if (msgtype == prop_atoms.net_active_window) { ob_debug("net_active_window for 0x%lx\n", client->window); - client_activate(client); + client_activate(client, FALSE); } else if (msgtype == prop_atoms.net_wm_moveresize) { ob_debug("net_wm_moveresize for 0x%lx\n", client->window); if ((Atom)e->xclient.data.l[2] == @@ -902,14 +994,30 @@ static void event_handle_client(ObClient *client, XEvent *e) if (e->xclient.data.l[0] & 1 << 10) w = e->xclient.data.l[3]; else - w = client->area.y; + w = client->area.width; if (e->xclient.data.l[0] & 1 << 11) h = e->xclient.data.l[4]; else - h = client->area.y; + h = client->area.height; client->gravity = tmpg; + + { + int newx = x; + int newy = y; + int fw = w + + client->frame->size.left + client->frame->size.right; + int fh = h + + client->frame->size.top + client->frame->size.bottom; + client_find_onscreen(client, &newx, &newy, fw, fh, TRUE); + if (e->xclient.data.l[0] & 1 << 8) + x = newx; + if (e->xclient.data.l[0] & 1 << 9) + y = newy; + } + client_configure(client, OB_CORNER_TOPLEFT, x, y, w, h, FALSE, TRUE); + client->gravity = oldg; } break; @@ -954,8 +1062,9 @@ static void event_handle_client(ObClient *client, XEvent *e) client_update_protocols(client); client_setup_decor_and_functions(client); } - else if (msgtype == prop_atoms.net_wm_strut) + else if (msgtype == prop_atoms.net_wm_strut) { client_update_strut(client); + } else if (msgtype == prop_atoms.net_wm_icon || msgtype == prop_atoms.kwm_win_icon) client_update_icons(client); @@ -1014,7 +1123,7 @@ static void event_handle_menu(ObClient *client, XEvent *e) /* will call the menu_hide() for each submenu as well */ if (!it) - menu_hide(menu_visible->data); + menu_control_keyboard_nav(ob_keycode(OB_KEY_ESCAPE)); break; case MotionNotify: @@ -1056,7 +1165,7 @@ static void find_max_fd() (gpointer)&tmpmax); max_fd = MAX(x_fd, tmpmax); #ifdef USE_SM - max_fd = MAX(ice_fd, tmpmax); + max_fd = MAX(ice_fd, max_fd); #endif }