static gboolean focus_delay_func(gpointer data);
static void focus_delay_client_dest(gpointer data);
+static gboolean menu_hide_delay_func(gpointer data);
+
#define INVALID_FOCUSIN(e) ((e)->xfocus.detail == NotifyInferior || \
(e)->xfocus.detail == NotifyAncestor || \
(e)->xfocus.detail > NotifyNonlinearVirtual)
static ObClient *focus_delay_client;
+static gboolean menu_can_hide;
+
#ifdef USE_SM
static void ice_handler(int fd, gpointer conn)
{
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);
{
if (menu_frame_visible)
event_handle_menu(e);
- else if (moveresize_in_progress)
- moveresize_event(e);
else {
- ObFrameContext context;
+ if (!keyboard_process_interactive_grab(e, &client)) {
+ if (moveresize_in_progress)
+ moveresize_event(e);
- context = frame_context(client, e->xany.window);
+ menu_can_hide = FALSE;
+ ob_main_loop_timeout_add(ob_main_loop,
+ G_USEC_PER_SEC / 4,
+ menu_hide_delay_func,
+ NULL, NULL);
- if (!keyboard_process_interactive_grab(e, &client, &context)) {
if (e->type == ButtonPress || e->type == ButtonRelease ||
e->type == MotionNotify)
- mouse_event(client, context, e);
+ mouse_event(client, 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 ? client : focus_client)), e);
}
}
}
/* Wheel buttons don't draw because they are an instant click, so it
is a waste of resources to go drawing it. */
if (!(e->xbutton.button == 4 || e->xbutton.button == 5)) {
- switch (frame_context(client, e->xbutton.window)) {
+ con = frame_context(client, e->xbutton.window);
+ con = mouse_button_frame_context(con, e->xbutton.button);
+ switch (con) {
case OB_FRAME_CONTEXT_MAXIMIZE:
client->frame->max_press = (e->type == ButtonPress);
framerender_frame(client->frame);
case OB_FRAME_CONTEXT_FRAME:
/* XXX if doing a 'reconfigure' make sure you kill this timer,
maybe all timers.. */
- if (config_focus_delay) {
+ 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;
- ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
}
default:
break;
ob_main_loop_timeout_add(ob_main_loop,
config_focus_delay,
focus_delay_func,
- NULL, NULL);
+ client, NULL);
focus_delay_client = client;
} else
client_focus(client);
switch (ev->type) {
case ButtonRelease:
- if (!(f = menu_frame_under(ev->xbutton.x_root,
- ev->xbutton.y_root)))
+ if ((e = menu_entry_frame_under(ev->xbutton.x_root,
+ ev->xbutton.y_root)))
+ menu_entry_frame_execute(e, ev->xbutton.state);
+ else if (menu_can_hide)
menu_frame_hide_all();
- else {
- if ((e = menu_entry_frame_under(ev->xbutton.x_root,
- ev->xbutton.y_root)))
- menu_entry_frame_execute(e,
- !(ev->xbutton.state & ControlMask));
- }
break;
case MotionNotify:
if ((f = menu_frame_under(ev->xmotion.x_root,
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)
}
}
+static gboolean menu_hide_delay_func(gpointer data)
+{
+ menu_can_hide = TRUE;
+ return FALSE; /* no repeat */
+}
+
static gboolean focus_delay_func(gpointer data)
{
client_focus(focus_delay_client);
{
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;
- ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
}
}