X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=c32d8bae630eeb67084b9ab67507f036cab43d69;hb=38370b2e82c20acc1a42a03e1e26bdc018a0b9e5;hp=dbb4ec68eb0b91874309d2ec4712618bf296743c;hpb=9e746b64390277e06c4be0b6afd863841cebed3e;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index dbb4ec68..c32d8bae 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -1,3 +1,21 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + event.c for the Openbox window manager + Copyright (c) 2003 Ben Jansens + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + See the COPYING file for a copy of the GNU General Public License. +*/ + #include "debug.h" #include "openbox.h" #include "dock.h" @@ -36,6 +54,11 @@ #include #endif +typedef struct +{ + gboolean ignored; +} ObEventData; + static void event_process(const XEvent *e, gpointer data); static void event_handle_root(XEvent *e); static void event_handle_menu(XEvent *e); @@ -72,6 +95,7 @@ static const int mask_table[] = { }; static int mask_table_size; +static guint ignore_enter_focus = 0; static ObClient *focus_delay_client; static gboolean menu_can_hide; @@ -289,8 +313,8 @@ static gboolean event_ignore(XEvent *e, ObClient *client) if (INVALID_FOCUSIN(e) || client == NULL) { #ifdef DEBUG_FOCUS - ob_debug("FocusIn on %lx mode %d detail %d IGNORED\n", - e->xfocus.window, e->xfocus.mode, e->xfocus.detail); + ob_debug("FocusIn on %lx mode %d detail %d IGNORED\n", + e->xfocus.window, e->xfocus.mode, e->xfocus.detail); #endif /* says a client was not found for the event (or a valid FocusIn event was not found. @@ -372,14 +396,20 @@ static gboolean event_ignore(XEvent *e, ObClient *client) } } - /* once all the FocusOut's have been dealt with, if there - is a FocusIn still left and it is valid, then use it */ - event_process(&fe, NULL); - /* secret magic way of event_process telling us that no - client was found for the FocusIn event. ^_^ */ - if (fe.xfocus.window != None) { - fallback = FALSE; - break; + { + ObEventData d; + + /* once all the FocusOut's have been dealt with, if + there is a FocusIn still left and it is valid, then + use it */ + event_process(&fe, &d); + if (!d.ignored) { +#ifdef DEBUG_FOCUS + ob_debug("FocusIn was OK, so don't fallback\n"); +#endif + fallback = FALSE; + break; + } } } } @@ -391,34 +421,7 @@ static gboolean event_ignore(XEvent *e, ObClient *client) focus_fallback(OB_FOCUS_FALLBACK_NOFOCUS); } } - break; - case EnterNotify: - case LeaveNotify: - /* NotifyUngrab occurs when a mouse button is released and the event is - caused, like when lowering a window */ - /* NotifyVirtual and NotifyAncestor occurs when ungrabbing the - pointer (Ancestor happens when the pointer is on a window border) */ - if (e->xcrossing.mode == NotifyGrab || - e->xcrossing.detail == NotifyInferior || - (e->xcrossing.mode == NotifyUngrab && - (e->xcrossing.detail == NotifyAncestor || - e->xcrossing.detail == NotifyNonlinearVirtual || - e->xcrossing.detail == NotifyVirtual))) { -#ifdef DEBUG_FOCUS - ob_debug("%sNotify mode %d detail %d on %lx IGNORED\n", - (e->type == EnterNotify ? "Enter" : "Leave"), - e->xcrossing.mode, - e->xcrossing.detail, client?client->window:0); -#endif - return TRUE; - } -#ifdef DEBUG_FOCUS - ob_debug("%sNotify mode %d detail %d on %lx\n", - (e->type == EnterNotify ? "Enter" : "Leave"), - e->xcrossing.mode, - e->xcrossing.detail, client?client->window:0); -#endif - break; + break; } return FALSE; } @@ -432,6 +435,7 @@ static void event_process(const XEvent *ec, gpointer data) ObDockApp *dockapp = NULL; ObWindow *obwin = NULL; XEvent ee, *e; + ObEventData *ed = data; /* make a copy we can mangle */ ee = *ec; @@ -461,8 +465,12 @@ static void event_process(const XEvent *ec, gpointer data) event_set_lasttime(e); event_hack_mods(e); - if (event_ignore(e, client)) + if (event_ignore(e, client)) { + if (ed) + ed->ignored = TRUE; return; + } else if (ed) + ed->ignored = FALSE; /* deal with it in the kernel */ if (group) @@ -507,9 +515,14 @@ static void event_process(const XEvent *ec, gpointer data) event_handle_menu(e); else { if (!keyboard_process_interactive_grab(e, &client)) { - if (moveresize_in_progress) + if (moveresize_in_progress) { moveresize_event(e); + /* make further actions work on the client being + moved/resized */ + client = moveresize_client; + } + menu_can_hide = FALSE; ob_main_loop_timeout_add(ob_main_loop, G_USEC_PER_SEC / 4, @@ -524,8 +537,7 @@ static void event_process(const XEvent *ec, gpointer data) causes the window which appears to be focused to be the one on which the actions will be executed */ keyboard_event((focus_cycle_target ? - focus_cycle_target : - (client ? client : focus_client)), e); + focus_cycle_target : client), e); } } } @@ -538,7 +550,7 @@ static void event_handle_root(XEvent *e) switch(e->type) { case SelectionClear: ob_debug("Another WM has requested to replace us. Exiting.\n"); - ob_exit(); + ob_exit(0); break; case ClientMessage: @@ -694,6 +706,14 @@ static void event_handle_client(ObClient *client, XEvent *e) } break; case EnterNotify: + { + gboolean nofocus = FALSE; + + if (ignore_enter_focus) { + ignore_enter_focus--; + nofocus = TRUE; + } + con = frame_context(client, e->xcrossing.window); switch (con) { case OB_FRAME_CONTEXT_MAXIMIZE: @@ -717,11 +737,23 @@ static void event_handle_client(ObClient *client, XEvent *e) frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_FRAME: - if (client_normal(client)) { - if (config_focus_follow) { + if (!nofocus && client_normal(client) && config_focus_follow) { + if (e->xcrossing.mode == NotifyGrab || + e->xcrossing.detail == NotifyInferior) + { #ifdef DEBUG_FOCUS - ob_debug("EnterNotify on %lx, focusing window\n", - client->window); + ob_debug("%sNotify mode %d detail %d on %lx IGNORED\n", + (e->type == EnterNotify ? "Enter" : "Leave"), + e->xcrossing.mode, + e->xcrossing.detail, client?client->window:0); +#endif + } else { +#ifdef DEBUG_FOCUS + ob_debug("%sNotify mode %d detail %d on %lx, " + "focusing window\n", + (e->type == EnterNotify ? "Enter" : "Leave"), + e->xcrossing.mode, + e->xcrossing.detail, client?client->window:0); #endif if (config_focus_delay) { ob_main_loop_timeout_add(ob_main_loop, @@ -738,6 +770,7 @@ static void event_handle_client(ObClient *client, XEvent *e) break; } break; + } case ConfigureRequest: /* compress these */ while (XCheckTypedWindowEvent(ob_display, client->window, @@ -1167,6 +1200,16 @@ static void event_handle_menu(XEvent *ev) ev->xmotion.y_root))) menu_frame_select(f, e); } + { + ObMenuFrame *a; + + a = find_active_menu(); + if (a && a != f && + a->selected->entry->type != OB_MENU_ENTRY_TYPE_SUBMENU) + { + menu_frame_select(a, NULL); + } + } break; case KeyPress: if (ev->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) @@ -1217,3 +1260,8 @@ static void focus_delay_client_dest(gpointer data) focus_delay_client = NULL; } } + +void event_ignore_enter_focus(guint num) +{ + ignore_enter_focus += num; +}