#include "stacking.h"
#include "extensions.h"
#include "translate.h"
+#include "ping.h"
#include <X11/Xlib.h>
#include <X11/Xatom.h>
{
ObClient *client;
Time time;
+ gulong serial;
} ObFocusDelayData;
typedef struct
Time event_curtime = CurrentTime;
Time event_last_user_time = CurrentTime;
/*! The serial of the current X event */
-gulong event_curserial;
+static gulong event_curserial;
static gboolean focus_left_screen = FALSE;
/*! A list of ObSerialRanges which are to be ignored for mouse enter events */
static GSList *ignore_serials = NULL;
event_last_user_time = CurrentTime;
event_curtime = t;
- event_curserial = 0;
}
static void event_hack_mods(XEvent *e)
magic. Our X core protocol stuff won't work, so we use this to
find what the modifier state is instead. */
if (XkbGetState(ob_display, XkbUseCoreKbd, &xkb_state) == Success)
- e->xkey.state = xkb_state.compat_state;
+ e->xkey.state =
+ modkeys_only_modifier_masks(xkb_state.compat_state);
else
#endif
{
client = WINDOW_AS_CLIENT(obwin);
break;
case Window_Menu:
- case Window_Internal:
/* not to be used for events */
g_assert_not_reached();
break;
+ case Window_Internal:
+ /* we don't do anything with events directly on these windows */
+ break;
}
}
else if (e->type == MapRequest)
client_manage(window);
else if (e->type == MappingNotify) {
- /* keyboard layout changes, reconfigure openbox. need to restart the
- modkeys system, but also to reload the key bindings. */
- ob_reconfigure();
+ /* keyboard layout changes for modifier mapping changes. reload the
+ modifier map, and rebind all the key bindings as appropriate */
+ ob_debug("Kepboard map changed. Reloading keyboard bindings.\n");
+ modkeys_shutdown(TRUE);
+ modkeys_startup(TRUE);
+ keyboard_rebind();
}
else if (e->type == ClientMessage) {
/* This is for _NET_WM_REQUEST_FRAME_EXTENTS messages. They come for
/* Otherwise only process it if it was physically on an openbox
internal window */
else {
- Window target, parent, root, *children;
- unsigned int nchildren;
ObWindow *w;
- /* Find the top level ancestor of the subwindow, besides the
- root */
- target = e->xbutton.subwindow;
- ob_debug("subwindow 0x%x\n", target);
- while (XQueryTree(ob_display, target, &root, &parent, &children,
- &nchildren) != 0)
- {
- XFree(children);
- if (parent == root) {
- ob_debug("parent is root\n");
- break;
- }
- target = parent;
- }
- ob_debug("toplevel 0x%x\n", target);
-
- w = g_hash_table_lookup(window_map, &target);
- ob_debug("w 0x%x\n", w);
-
- if ((w = g_hash_table_lookup(window_map, &target)) &&
+ if ((w = g_hash_table_lookup(window_map, &e->xbutton.subwindow)) &&
WINDOW_IS_INTERNAL(w))
{
event_handle_user_input(client, e);
/* if something happens and it's not from an XEvent, then we don't know
the time */
event_curtime = CurrentTime;
+ event_curserial = 0;
}
static void event_handle_root(XEvent *e)
ob_restart();
else if (e->xclient.data.l[0] == 3)
ob_exit(0);
+ } else if (msgtype == prop_atoms.wm_protocols) {
+ if ((Atom)e->xclient.data.l[0] == prop_atoms.net_wm_ping)
+ ping_got_pong(e->xclient.data.l[1]);
}
break;
case PropertyNotify:
data = g_new(ObFocusDelayData, 1);
data->client = client;
data->time = event_curtime;
+ data->serial = event_curserial;
ob_main_loop_timeout_add(ob_main_loop,
config_focus_delay * 1000,
ObFocusDelayData data;
data.client = client;
data.time = event_curtime;
+ data.serial = event_curserial;
focus_delay_func(&data);
}
}
/* Allow control while going thru the menu */
else if (ev->type == KeyPress && (state & ~ControlMask) == 0) {
+ frame->got_press = TRUE;
+
if (keycode == ob_keycode(OB_KEY_ESCAPE)) {
menu_frame_hide_all();
ret = TRUE;
Allow ControlMask only, and don't bother if the menu is empty */
else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 &&
- frame->entries)
+ frame->entries && frame->got_press)
{
if (keycode == ob_keycode(OB_KEY_RETURN)) {
/* Enter runs the active item or goes into the submenu.
if (menu_frame_visible || moveresize_in_progress) return FALSE;
event_curtime = d->time;
+ event_curserial = d->serial;
if (client_focus(d->client) && config_focus_raise)
stacking_raise(CLIENT_AS_WINDOW(d->client));
event_curtime = old;
client, FALSE);
}
-void event_halt_focus_delay(gulong serial)
+void event_halt_focus_delay(void)
{
/* ignore all enter events up till the event which caused this to occur */
if (event_curserial) event_ignore_enter_range(1, event_curserial);
gulong event_start_ignore_all_enters(void)
{
- /* increment the serial so we don't ignore events we weren't meant to */
- XSync(ob_display, FALSE);
- return LastKnownRequestProcessed(ob_display);
+ return NextRequest(ob_display);
}
static void event_ignore_enter_range(gulong start, gulong end)
r->start, r->end);
/* increment the serial so we don't ignore events we weren't meant to */
- XSync(ob_display, FALSE);
+ PROP_ERASE(screen_support_win, motif_wm_hints);
}
void event_end_ignore_all_enters(gulong start)
{
- event_ignore_enter_range(start, LastKnownRequestProcessed(ob_display));
+ event_ignore_enter_range(start, NextRequest(ob_display));
}
static gboolean is_enter_focus_event_ignored(XEvent *e)
}
else
ungrab_passive_key();
+
+ XSync(ob_display, FALSE);
}
gboolean event_time_after(Time t1, Time t2)