#include "window.h"
#include "openbox.h"
#include "dock.h"
+#include "actions.h"
#include "client.h"
#include "xerror.h"
#include "prop.h"
#include "menuframe.h"
#include "keyboard.h"
#include "modkeys.h"
-#include "propwin.h"
#include "mouse.h"
#include "mainloop.h"
-#include "framerender.h"
#include "focus.h"
#include "focus_cycle.h"
#include "moveresize.h"
static void event_handle_dock(ObDock *s, XEvent *e);
static void event_handle_dockapp(ObDockApp *app, XEvent *e);
static void event_handle_client(ObClient *c, XEvent *e);
-static void event_handle_user_time_window_clients(GSList *l, XEvent *e);
static void event_handle_user_input(ObClient *client, XEvent *e);
static gboolean is_enter_focus_event_ignored(XEvent *e);
static gboolean focus_delay_func(gpointer data);
static void focus_delay_client_dest(ObClient *client, gpointer data);
-/* The time for the current event being processed */
Time event_curtime = CurrentTime;
+Time event_last_user_time = CurrentTime;
static gboolean focus_left_screen = FALSE;
/*! A list of ObSerialRanges which are to be ignored for mouse enter events */
break;
}
+ /* watch that if we get an event earlier than the last specified user_time,
+ which can happen if the clock goes backwards, we erase the last
+ specified user_time */
+ if (t && event_last_user_time && event_time_after(event_last_user_time, t))
+ event_last_user_time = CurrentTime;
+
event_curtime = t;
}
static void event_hack_mods(XEvent *e)
{
-#ifdef XKB
- XkbStateRec xkb_state;
-#endif
-
switch (e->type) {
case ButtonPress:
case ButtonRelease:
break;
case KeyRelease:
e->xkey.state = modkeys_only_modifier_masks(e->xkey.state);
-#ifdef XKB
- if (XkbGetState(ob_display, XkbUseCoreKbd, &xkb_state) == Success) {
- e->xkey.state = xkb_state.compat_state;
- break;
- }
-#endif
/* remove from the state the mask of the modifier key being released,
if it is a modifier key being released that is */
e->xkey.state &= ~modkeys_keycode_to_mask(e->xkey.keycode);
ObDock *dock = NULL;
ObDockApp *dockapp = NULL;
ObWindow *obwin = NULL;
- GSList *timewinclients = NULL;
XEvent ee, *e;
ObEventData *ed = data;
e = ⅇ
window = event_get_window(e);
- if (e->type != PropertyNotify ||
- !(timewinclients = propwin_get_clients(window,
- OB_PROPWIN_USER_TIME)))
- if ((obwin = g_hash_table_lookup(window_map, &window))) {
- switch (obwin->type) {
- case Window_Dock:
- dock = WINDOW_AS_DOCK(obwin);
- break;
- case Window_DockApp:
- dockapp = WINDOW_AS_DOCKAPP(obwin);
- break;
- case Window_Client:
- client = WINDOW_AS_CLIENT(obwin);
- break;
- case Window_Menu:
- case Window_Internal:
- /* not to be used for events */
- g_assert_not_reached();
- break;
- }
+ if ((obwin = g_hash_table_lookup(window_map, &window))) {
+ switch (obwin->type) {
+ case Window_Dock:
+ dock = WINDOW_AS_DOCK(obwin);
+ break;
+ case Window_DockApp:
+ dockapp = WINDOW_AS_DOCKAPP(obwin);
+ break;
+ case Window_Client:
+ client = WINDOW_AS_CLIENT(obwin);
+ break;
+ case Window_Menu:
+ case Window_Internal:
+ /* not to be used for events */
+ g_assert_not_reached();
+ break;
}
+ }
event_set_curtime(e);
event_hack_mods(e);
focus_left_screen = FALSE;
- focus_fallback(FALSE, FALSE, TRUE);
+ focus_fallback(FALSE, config_focus_under_mouse, TRUE, TRUE);
/* We don't get a FocusOut for this case, because it's just moving
from our Inferior up to us. This happens when iconifying a
/* focus_set_client(NULL) has already been called */
client_calc_layer(client);
}
- if (e->xfocus.detail == NotifyPointerRoot ||
- e->xfocus.detail == NotifyDetailNone ||
- e->xfocus.detail == NotifyInferior ||
- e->xfocus.detail == NotifyNonlinear)
+ else if (e->xfocus.detail == NotifyPointerRoot ||
+ e->xfocus.detail == NotifyDetailNone ||
+ e->xfocus.detail == NotifyInferior ||
+ e->xfocus.detail == NotifyNonlinear)
{
XEvent ce;
*/
if (!focus_left_screen)
- focus_fallback(FALSE, FALSE, TRUE);
+ focus_fallback(FALSE, config_focus_under_mouse,
+ TRUE, TRUE);
}
}
else if (!client)
ob_debug_type(OB_DEBUG_FOCUS,
"Focus went to an unmanaged window 0x%x !\n",
ce.xfocus.window);
- focus_fallback(TRUE, FALSE, TRUE);
+ focus_fallback(TRUE, config_focus_under_mouse, TRUE, TRUE);
}
}
section or by focus_fallback */
client_calc_layer(client);
}
- } else if (timewinclients)
- event_handle_user_time_window_clients(timewinclients, e);
+ }
else if (client)
event_handle_client(client, e);
else if (dockapp)
xwc.border_width = e->xconfigurerequest.border_width;
xwc.sibling = e->xconfigurerequest.above;
xwc.stack_mode = e->xconfigurerequest.detail;
-
+
/* we are not to be held responsible if someone sends us an
invalid request! */
xerror_set_ignore(TRUE);
static void event_handle_root(XEvent *e)
{
Atom msgtype;
-
+
switch(e->type) {
case SelectionClear:
ob_debug("Another WM has requested to replace us. Exiting.\n");
} else if (msgtype == prop_atoms.net_showing_desktop) {
screen_show_desktop(e->xclient.data.l[0] != 0, NULL);
} else if (msgtype == prop_atoms.ob_control) {
+ ob_debug("OB_CONTROL: %d\n", e->xclient.data.l[0]);
if (e->xclient.data.l[0] == 1)
ob_reconfigure();
else if (e->xclient.data.l[0] == 2)
}
break;
case PropertyNotify:
- if (e->xproperty.atom == prop_atoms.net_desktop_names)
+ if (e->xproperty.atom == prop_atoms.net_desktop_names) {
+ ob_debug("UPDATE DESKTOP NAMES\n");
screen_update_desktop_names();
+ }
else if (e->xproperty.atom == prop_atoms.net_desktop_layout)
screen_update_layout();
break;
data->time = event_curtime;
ob_main_loop_timeout_add(ob_main_loop,
- config_focus_delay,
+ config_focus_delay * 1000,
focus_delay_func,
data, focus_delay_cmp, focus_delay_dest);
} else {
}
}
-static void event_handle_user_time_window_clients(GSList *l, XEvent *e)
-{
- g_assert(e->type == PropertyNotify);
- if (e->xproperty.atom == prop_atoms.net_wm_user_time) {
- for (; l; l = g_slist_next(l))
- client_update_user_time(l->data);
- }
-}
-
static void event_handle_client(ObClient *client, XEvent *e)
{
XEvent ce;
ObFrameContext con;
static gint px = -1, py = -1;
static guint pb = 0;
-
+
switch (e->type) {
case ButtonPress:
/* save where the press occured for the first button pressed */
want to deal with them
*/
if (!(e->xbutton.button == 4 || e->xbutton.button == 5) &&
- !keyboard_interactively_grabbed() &&
- !menu_frame_visible)
+ !grab_on_keyboard())
{
/* use where the press occured */
con = frame_context(client, e->xbutton.window, px, py);
switch (con) {
case OB_FRAME_CONTEXT_MAXIMIZE:
client->frame->max_press = (e->type == ButtonPress);
- framerender_frame(client->frame);
+ frame_adjust_state(client->frame);
break;
case OB_FRAME_CONTEXT_CLOSE:
client->frame->close_press = (e->type == ButtonPress);
- framerender_frame(client->frame);
+ frame_adjust_state(client->frame);
break;
case OB_FRAME_CONTEXT_ICONIFY:
client->frame->iconify_press = (e->type == ButtonPress);
- framerender_frame(client->frame);
+ frame_adjust_state(client->frame);
break;
case OB_FRAME_CONTEXT_ALLDESKTOPS:
client->frame->desk_press = (e->type == ButtonPress);
- framerender_frame(client->frame);
- break;
+ frame_adjust_state(client->frame);
+ break;
case OB_FRAME_CONTEXT_SHADE:
client->frame->shade_press = (e->type == ButtonPress);
- framerender_frame(client->frame);
+ frame_adjust_state(client->frame);
break;
default:
/* nothing changes with clicks for any other contexts */
(e->type == EnterNotify ? "Enter" : "Leave"),
e->xcrossing.mode,
e->xcrossing.detail, (client?client->window:0));
- if (keyboard_interactively_grabbed())
+ if (grab_on_keyboard())
break;
if (config_focus_follow && config_focus_delay &&
/* leave inferior events can happen when the mouse goes onto
frame_adjust_state(client->frame);
break;
case OB_FRAME_CONTEXT_FRAME:
- if (keyboard_interactively_grabbed())
+ if (grab_on_keyboard())
break;
if (e->xcrossing.mode == NotifyGrab ||
e->xcrossing.mode == NotifyUngrab ||
if (e->xconfigurerequest.value_mask & CWStackMode) {
ObClient *sibling = NULL;
gulong ignore_start;
+ gboolean ok = TRUE;
/* get the sibling */
if (e->xconfigurerequest.value_mask & CWSibling) {
ObWindow *win;
win = g_hash_table_lookup(window_map,
&e->xconfigurerequest.above);
- if (WINDOW_IS_CLIENT(win) && WINDOW_AS_CLIENT(win) != client)
+ if (win && WINDOW_IS_CLIENT(win) &&
+ WINDOW_AS_CLIENT(win) != client)
+ {
sibling = WINDOW_AS_CLIENT(win);
+ }
+ else
+ /* an invalid sibling was specified so don't restack at
+ all, it won't make sense no matter what we do */
+ ok = FALSE;
}
- /* activate it rather than just focus it */
- if (!config_focus_under_mouse)
- ignore_start = event_start_ignore_all_enters();
- stacking_restack_request(client, sibling,
- e->xconfigurerequest.detail,
- TRUE);
- if (!config_focus_under_mouse)
- event_end_ignore_all_enters(ignore_start);
+ if (ok) {
+ if (!config_focus_under_mouse)
+ ignore_start = event_start_ignore_all_enters();
+ stacking_restack_request(client, sibling,
+ e->xconfigurerequest.detail);
+ if (!config_focus_under_mouse)
+ event_end_ignore_all_enters(ignore_start);
+ }
- /* if a stacking change moves the window without resizing */
+ /* a stacking change moves the window without resizing */
move = TRUE;
}
notify is sent or not */
}
- if (move || resize) {
+ {
gint lw,lh;
client_try_configure(client, &x, &y, &w, &h, &lw, &lh, FALSE);
client_find_onscreen(client, &x, &y, w, h, 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)) {
- gulong ignore_start;
-
- ob_debug("Granting ConfigureRequest x %d y %d w %d h %d\n",
- x, y, w, h);
- ignore_start = event_start_ignore_all_enters();
- client_configure(client, x, y, w, h, FALSE, TRUE);
- event_end_ignore_all_enters(ignore_start);
- }
+ ob_debug("Granting ConfigureRequest x %d y %d w %d h %d\n",
+ x, y, w, h);
+ client_configure(client, x, y, w, h, FALSE, TRUE, TRUE);
}
break;
}
/* we don't want the reparent event, put it back on the stack for the
X server to deal with after we unmanage the window */
XPutBackEvent(ob_display, e);
-
+
ob_debug("ReparentNotify for window 0x%x\n", client->window);
client_unmanage(client);
break;
it can happen now when the window is on
another desktop, but we still don't
want it! */
- client_activate(client, FALSE, TRUE);
+ client_activate(client, FALSE, TRUE, TRUE, TRUE);
break;
case ClientMessage:
/* validate cuz we query stuff off the client here */
if ((unsigned)e->xclient.data.l[0] < screen_num_desktops ||
(unsigned)e->xclient.data.l[0] == DESKTOP_ALL)
client_set_desktop(client, (unsigned)e->xclient.data.l[0],
- FALSE);
+ FALSE, FALSE);
} else if (msgtype == prop_atoms.net_wm_state) {
gulong ignore_start;
(e->xclient.data.l[0] == 2 ? "user" : "INVALID"))));
/* XXX make use of data.l[2] !? */
if (e->xclient.data.l[0] == 1 || e->xclient.data.l[0] == 2) {
- event_curtime = e->xclient.data.l[1];
- if (event_curtime == 0)
+ /* don't use the user's timestamp for client_focus, cuz if it's
+ an old broken timestamp (happens all the time) then focus
+ won't move even though we're trying to move it
+ event_curtime = e->xclient.data.l[1];*/
+ if (e->xclient.data.l[1] == 0)
ob_debug_type(OB_DEBUG_APP_BUGS,
"_NET_ACTIVE_WINDOW message for window %s is"
" missing a timestamp\n", client->title);
ob_debug_type(OB_DEBUG_APP_BUGS,
"_NET_ACTIVE_WINDOW message for window %s is "
"missing source indication\n");
- client_activate(client, FALSE,
+ client_activate(client, FALSE, TRUE, TRUE,
(e->xclient.data.l[0] == 0 ||
e->xclient.data.l[0] == 2));
} else if (msgtype == prop_atoms.net_wm_moveresize) {
moveresize_end(TRUE);
} else if (msgtype == prop_atoms.net_moveresize_window) {
gint ograv, x, y, w, h;
- gulong ignore_start;
ograv = client->gravity;
client_find_onscreen(client, &x, &y, w, h, FALSE);
- /* ignore enter events caused by these like ob actions do */
- ignore_start = event_start_ignore_all_enters();
- client_configure(client, x, y, w, h, FALSE, TRUE);
- event_end_ignore_all_enters(ignore_start);
+ client_configure(client, x, y, w, h, FALSE, TRUE, FALSE);
client->gravity = ograv;
} else if (msgtype == prop_atoms.net_restack_window) {
ignore_start = event_start_ignore_all_enters();
/* just raise, don't activate */
stacking_restack_request(client, sibling,
- e->xclient.data.l[2], FALSE);
+ e->xclient.data.l[2]);
if (!config_focus_under_mouse)
event_end_ignore_all_enters(ignore_start);
/* send a synthetic ConfigureNotify, cuz this is supposed
to be like a ConfigureRequest. */
- client_reconfigure(client);
+ client_reconfigure(client, TRUE);
} else
ob_debug_type(OB_DEBUG_APP_BUGS,
"_NET_RESTACK_WINDOW sent for window %s "
case PropertyNotify:
/* validate cuz we query stuff off the client here */
if (!client_validate(client)) break;
-
+
/* compress changes to a single property into a single change */
while (XCheckTypedWindowEvent(ob_display, client->window,
e->type, &ce)) {
msgtype = e->xproperty.atom;
if (msgtype == XA_WM_NORMAL_HINTS) {
+ ob_debug("Update NORMAL hints\n");
client_update_normal_hints(client);
/* normal hints can make a window non-resizable */
- client_setup_decor_and_functions(client, TRUE);
+ client_setup_decor_and_functions(client, FALSE);
+
+ /* make sure the client's sizes are within its bounds, but only
+ reconfigure the window if it needs to. emacs will update its
+ normal hints every time it receives a conigurenotify */
+ client_reconfigure(client, FALSE);
} else if (msgtype == XA_WM_HINTS) {
client_update_wmhints(client);
} else if (msgtype == XA_WM_TRANSIENT_FOR) {
client_update_icon_geometry(client);
}
else if (msgtype == prop_atoms.net_wm_user_time) {
- client_update_user_time(client);
- }
- else if (msgtype == prop_atoms.net_wm_user_time_window) {
- client_update_user_time_window(client);
+ guint32 t;
+ if (client == focus_client &&
+ PROP_GET32(client->window, net_wm_user_time, cardinal, &t) &&
+ t && !event_time_after(t, e->xproperty.time) &&
+ (!event_last_user_time ||
+ event_time_after(t, event_last_user_time)))
+ {
+ event_last_user_time = t;
+ }
}
#ifdef SYNC
else if (msgtype == prop_atoms.net_wm_sync_request_counter) {
guint keycode, state;
gunichar unikey;
ObMenuFrame *frame;
- gboolean ret = TRUE;
+ gboolean ret = FALSE;
keycode = ev->xkey.keycode;
state = ev->xkey.state;
frame = find_active_or_last_menu();
if (frame == NULL)
- ret = FALSE;
+ g_assert_not_reached(); /* there is no active menu */
- else if (keycode == ob_keycode(OB_KEY_ESCAPE) && state == 0)
- menu_frame_hide_all();
+ /* Allow control while going thru the menu */
+ else if (ev->type == KeyPress && (state & ~ControlMask) == 0) {
+ if (keycode == ob_keycode(OB_KEY_ESCAPE)) {
+ menu_frame_hide_all();
+ ret = TRUE;
+ }
- else if (keycode == ob_keycode(OB_KEY_RETURN) && (state == 0 ||
- state == ControlMask))
- {
- /* Enter runs the active item or goes into the submenu.
- Control-Enter runs it without closing the menu. */
- if (frame->child)
- menu_frame_select_next(frame->child);
- else if (frame->selected)
- menu_entry_frame_execute(frame->selected, state, ev->xkey.time);
- }
+ else if (keycode == ob_keycode(OB_KEY_LEFT)) {
+ /* Left goes to the parent menu */
+ menu_frame_select(frame, NULL, TRUE);
+ ret = TRUE;
+ }
- else if (keycode == ob_keycode(OB_KEY_LEFT) && ev->xkey.state == 0) {
- /* Left goes to the parent menu */
- menu_frame_select(frame, NULL, TRUE);
- }
+ else if (keycode == ob_keycode(OB_KEY_RIGHT)) {
+ /* Right goes to the selected submenu */
+ if (frame->child) menu_frame_select_next(frame->child);
+ ret = TRUE;
+ }
- else if (keycode == ob_keycode(OB_KEY_RIGHT) && ev->xkey.state == 0) {
- /* Right goes to the selected submenu */
- if (frame->child) menu_frame_select_next(frame->child);
- }
+ else if (keycode == ob_keycode(OB_KEY_UP)) {
+ menu_frame_select_previous(frame);
+ ret = TRUE;
+ }
- else if (keycode == ob_keycode(OB_KEY_UP) && state == 0) {
- menu_frame_select_previous(frame);
+ else if (keycode == ob_keycode(OB_KEY_DOWN)) {
+ menu_frame_select_next(frame);
+ ret = TRUE;
+ }
}
- else if (keycode == ob_keycode(OB_KEY_DOWN) && state == 0) {
- menu_frame_select_next(frame);
- }
+ /* Use KeyRelease events for running things so that the key release doesn't
+ get sent to the focused application.
- /* keyboard accelerator shortcuts. (allow controlmask) */
- else if ((ev->xkey.state & ~ControlMask) == 0 &&
- /* was it a valid key? */
- unikey != 0 &&
- /* don't bother if the menu is empty. */
+ Allow ControlMask only, and don't bother if the menu is empty */
+ else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 &&
frame->entries)
{
- GList *start;
- GList *it;
- ObMenuEntryFrame *found = NULL;
- guint num_found = 0;
-
- /* start after the selected one */
- start = frame->entries;
- if (frame->selected) {
- for (it = start; frame->selected != it->data; it = g_list_next(it))
- g_assert(it != NULL); /* nothing was selected? */
- /* next with wraparound */
- start = g_list_next(it);
- if (start == NULL) start = frame->entries;
+ if (keycode == ob_keycode(OB_KEY_RETURN)) {
+ /* Enter runs the active item or goes into the submenu.
+ Control-Enter runs it without closing the menu. */
+ if (frame->child)
+ menu_frame_select_next(frame->child);
+ else if (frame->selected)
+ menu_entry_frame_execute(frame->selected, state);
+
+ ret = TRUE;
}
- it = start;
- do {
- ObMenuEntryFrame *e = it->data;
- gunichar entrykey = 0;
+ /* keyboard accelerator shortcuts. (if it was a valid key) */
+ else if (unikey != 0) {
+ GList *start;
+ GList *it;
+ ObMenuEntryFrame *found = NULL;
+ guint num_found = 0;
+
+ /* start after the selected one */
+ start = frame->entries;
+ if (frame->selected) {
+ for (it = start; frame->selected != it->data;
+ it = g_list_next(it))
+ g_assert(it != NULL); /* nothing was selected? */
+ /* next with wraparound */
+ start = g_list_next(it);
+ if (start == NULL) start = frame->entries;
+ }
- if (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL)
- entrykey = e->entry->data.normal.shortcut;
- else if (e->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)
- entrykey = e->entry->data.submenu.submenu->shortcut;
+ it = start;
+ do {
+ ObMenuEntryFrame *e = it->data;
+ gunichar entrykey = 0;
- if (unikey == entrykey) {
- if (found == NULL) found = e;
- ++num_found;
- }
+ if (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL)
+ entrykey = e->entry->data.normal.shortcut;
+ else if (e->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)
+ entrykey = e->entry->data.submenu.submenu->shortcut;
- /* next with wraparound */
- it = g_list_next(it);
- if (it == NULL) it = frame->entries;
- } while (it != start);
+ if (unikey == entrykey) {
+ if (found == NULL) found = e;
+ ++num_found;
+ }
- if (found) {
- if (found->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
- num_found == 1)
- {
- menu_frame_select(frame, found, TRUE);
- usleep(50000); /* highlight the item for a short bit so the
- user can see what happened */
- menu_entry_frame_execute(found, state, ev->xkey.time);
- } else {
- menu_frame_select(frame, found, TRUE);
- if (num_found == 1)
- menu_frame_select_next(frame->child);
+ /* next with wraparound */
+ it = g_list_next(it);
+ if (it == NULL) it = frame->entries;
+ } while (it != start);
+
+ if (found) {
+ if (found->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
+ num_found == 1)
+ {
+ menu_frame_select(frame, found, TRUE);
+ usleep(50000); /* highlight the item for a short bit so the
+ user can see what happened */
+ menu_entry_frame_execute(found, state);
+ } else {
+ menu_frame_select(frame, found, TRUE);
+ if (num_found == 1)
+ menu_frame_select_next(frame->child);
+ }
+
+ ret = TRUE;
}
- } else
- ret = FALSE;
+ }
}
- else
- ret = FALSE;
return ret;
}
ev->xbutton.y_root)))
{
menu_frame_select(e->frame, e, TRUE);
- menu_entry_frame_execute(e, ev->xbutton.state,
- ev->xbutton.time);
+ menu_entry_frame_execute(e, ev->xbutton.state);
}
else
menu_frame_hide_all();
menu_frame_select(e->frame, NULL, FALSE);
}
break;
- case MotionNotify:
- if ((e = menu_entry_frame_under(ev->xmotion.x_root,
+ case MotionNotify:
+ if ((e = menu_entry_frame_under(ev->xmotion.x_root,
ev->xmotion.y_root)))
if (!(f = find_active_menu()) ||
f == e->frame ||
menu_frame_select(e->frame, e, FALSE);
break;
case KeyPress:
+ case KeyRelease:
ret = event_handle_menu_keyboard(ev);
break;
}
/* if the keyboard interactive action uses the event then dont
use it for bindings. likewise is moveresize uses the event. */
- if (!keyboard_process_interactive_grab(e, &client) &&
- !(moveresize_in_progress && moveresize_event(e)))
- {
+ if (!actions_interactive_input_event(e) && !moveresize_event(e)) {
if (moveresize_in_progress)
/* make further actions work on the client being
moved/resized */
in the case where it is animating before disappearing */
if (!client || !frame_iconify_animating(client->frame))
mouse_event(client, e);
- } else if (e->type == KeyPress) {
+ } else
keyboard_event((focus_cycle_target ? focus_cycle_target :
(client ? client : focus_client)), e);
- }
}
}
ObFocusDelayData *d = data;
Time old = event_curtime;
+ /* don't move focus and kill the menu or the move/resize */
+ if (menu_frame_visible || moveresize_in_progress) return FALSE;
+
event_curtime = d->time;
if (focus_client != d->client) {
if (client_focus(d->client) && config_focus_raise)
r->start = start;
r->end = LastKnownRequestProcessed(ob_display);
ignore_serials = g_slist_prepend(ignore_serials, r);
- ob_debug("ignoring serials %u-%u\n", r->start, r->end);
/* increment the serial so we don't ignore events we weren't meant to */
XSync(ob_display, FALSE);
- ob_debug("now last serial %u\n", LastKnownRequestProcessed(ob_display));
}
static gboolean is_enter_focus_event_ignored(XEvent *e)
e->xcrossing.mode == NotifyUngrab ||
e->xcrossing.detail == NotifyInferior));
- ob_debug("checking serial %u\n", e->xany.serial);
for (it = ignore_serials; it; it = next) {
ObSerialRange *r = it->data;
next = g_slist_next(it);
- /* XXX wraparound... */
- ob_debug(" ignore range %u-%u\n", r->start, r->end);
if ((glong)(e->xany.serial - r->end) > 0) {
/* past the end */
ignore_serials = g_slist_delete_link(ignore_serials, it);
void event_cancel_all_key_grabs()
{
- if (keyboard_interactively_grabbed())
- keyboard_interactive_cancel();
- else if (menu_frame_visible)
+ if (actions_interactive_act_running()) {
+ actions_interactive_cancel_act();
+ ob_debug("KILLED interactive action\n");
+ }
+ else if (menu_frame_visible) {
menu_frame_hide_all();
- else if (grab_on_keyboard())
+ ob_debug("KILLED open menus\n");
+ }
+ else if (moveresize_in_progress) {
+ moveresize_end(TRUE);
+ ob_debug("KILLED interactive moveresize\n");
+ }
+ else if (grab_on_keyboard()) {
ungrab_keyboard();
+ ob_debug("KILLED active grab on keyboard\n");
+ }
else
- /* If we don't have the keyboard grabbed, then ungrab it with
- XUngrabKeyboard, so that there is not a passive grab left
- on from the KeyPress. If the grab is left on, and focus
- moves during that time, it will be NotifyWhileGrabbed, and
- applications like to ignore those! */
- if (!keyboard_interactively_grabbed())
- XUngrabKeyboard(ob_display, CurrentTime);
-
+ ungrab_passive_key();
}
gboolean event_time_after(Time t1, Time t2)
/* t2 is in the first half so t1 has to come after it */
return t1 >= t2 && t1 < (t2 + TIME_HALF);
}
+
+Time event_get_server_time()
+{
+ /* Generate a timestamp */
+ XEvent event;
+
+ XChangeProperty(ob_display, screen_support_win,
+ prop_atoms.wm_class, prop_atoms.string,
+ 8, PropModeAppend, NULL, 0);
+ XWindowEvent(ob_display, screen_support_win, PropertyChangeMask, &event);
+ return event.xproperty.time;
+}