#include <X11/Xatom.h>
#include <glib.h>
-#ifdef USE_LIBSN
-# include <libsn/sn.h>
-#endif
-
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
static void event_handle_dockapp(ObDockApp *app, XEvent *e);
static void event_handle_client(ObClient *c, XEvent *e);
+static gboolean focus_delay_func(gpointer data);
+static void focus_delay_client_dest(gpointer data);
+
#define INVALID_FOCUSIN(e) ((e)->xfocus.detail == NotifyInferior || \
(e)->xfocus.detail == NotifyAncestor || \
(e)->xfocus.detail > NotifyNonlinearVirtual)
};
static int mask_table_size;
+static ObClient *focus_delay_client;
+
#ifdef USE_SM
static void ice_handler(int fd, gpointer conn)
{
}
#endif
-#ifdef USE_LIBSN
-static void sn_handler(const XEvent *e, gpointer display)
+void event_startup(gboolean reconfig)
{
- XEvent ec;
- ec = *e;
- sn_display_process_event(display, &ec);
-}
-#endif
-
+ if (reconfig) return;
-void event_startup()
-{
mask_table_size = sizeof(mask_table) / sizeof(mask_table[0]);
/* get lock masks that are defined by the display (not constant) */
IceAddConnectionWatch(ice_watch, NULL);
#endif
-#ifdef USE_LIBSN
- ob_main_loop_x_add(ob_main_loop, sn_handler, ob_sn_display, NULL);
-#endif
+ client_add_destructor(focus_delay_client_dest);
}
-void event_shutdown()
+void event_shutdown(gboolean reconfig)
{
+ if (reconfig) return;
+
+ client_remove_destructor(focus_delay_client_dest);
XFreeModifiermap(modmap);
}
break;
if (fe.type == FocusOut) {
#ifdef DEBUG_FOCUS
- ob_debug("found pending FocusOut");
+ ob_debug("found pending FocusOut\n");
#endif
if (!INVALID_FOCUSOUT(&fe)) {
/* if there is a VALID FocusOut still coming, don't
}
} else {
#ifdef DEBUG_FOCUS
- ob_debug("found pending FocusIn");
+ ob_debug("found pending FocusIn\n");
#endif
/* is the focused window getting a FocusOut/In back to
itself?
if (focus_client) {
#ifdef DEBUG_FOCUS
ob_debug("focused window got an Out/In back to "
- "itself IGNORED both");
+ "itself IGNORED both\n");
#endif
return TRUE;
} else {
#ifdef DEBUG_FOCUS
ob_debug("focused window got an Out/In back to "
"itself but focus_client was null "
- "IGNORED just the Out");
+ "IGNORED just the Out\n");
#endif
return TRUE;
}
if (fallback) {
#ifdef DEBUG_FOCUS
ob_debug("no valid FocusIn and no FocusOut events found, "
- "falling back");
+ "falling back\n");
#endif
focus_fallback(OB_FOCUS_FALLBACK_NOFOCUS);
}
(e->xcrossing.mode == NotifyUngrab &&
e->xcrossing.detail == NotifyVirtual)) {
#ifdef DEBUG_FOCUS
- ob_debug("%sNotify mode %d detail %d on %lx IGNORED",
+ 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);
return TRUE;
}
#ifdef DEBUG_FOCUS
- ob_debug("%sNotify mode %d detail %d on %lx",
+ 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);
e->type == MotionNotify)
mouse_event(client, context, e);
else if (e->type == KeyPress)
- keyboard_event(client, e);
+ /* when in the middle of a focus cycling action, this
+ 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), e);
}
}
}
client->frame->close_hover = FALSE;
frame_adjust_state(client->frame);
break;
+ case OB_FRAME_CONTEXT_FRAME:
+ /* XXX if doing a 'reconfigure' make sure you kill this timer,
+ maybe all timers.. */
+ if (config_focus_delay && client == focus_delay_client) {
+ ob_main_loop_timeout_remove_data(ob_main_loop,
+ focus_delay_func,
+ focus_delay_client);
+ focus_delay_client = NULL;
+ }
default:
break;
}
ob_debug("EnterNotify on %lx, focusing window\n",
client->window);
#endif
- client_focus(client);
+ if (config_focus_delay) {
+ ob_main_loop_timeout_add(ob_main_loop,
+ config_focus_delay,
+ focus_delay_func,
+ client, NULL);
+ focus_delay_client = client;
+ } else
+ client_focus(client);
}
}
break;
else {
if ((e = menu_entry_frame_under(ev->xbutton.x_root,
ev->xbutton.y_root)))
- menu_entry_frame_execute(e,
- !(ev->xbutton.state & ControlMask));
+ menu_entry_frame_execute(e, ev->xbutton.state);
}
break;
case MotionNotify:
else if (ev->xkey.keycode == ob_keycode(OB_KEY_RETURN)) {
ObMenuFrame *f;
if ((f = find_active_menu()))
- menu_entry_frame_execute(f->selected,
- !(ev->xkey.state & ControlMask));
+ menu_entry_frame_execute(f->selected, ev->xkey.state);
} else if (ev->xkey.keycode == ob_keycode(OB_KEY_LEFT)) {
ObMenuFrame *f;
if ((f = find_active_menu()) && f->parent)
break;
}
}
+
+static gboolean focus_delay_func(gpointer data)
+{
+ client_focus(focus_delay_client);
+ return FALSE; /* no repeat */
+}
+
+static void focus_delay_client_dest(gpointer data)
+{
+ ObClient *c = data;
+ if (c == focus_delay_client) {
+ ob_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func,
+ focus_delay_client);
+ focus_delay_client = NULL;
+ }
+}