#include "openbox.h"
+#include "slit.h"
#include "client.h"
#include "xerror.h"
#include "prop.h"
static void event_process(XEvent *e);
static void event_handle_root(XEvent *e);
+static void event_handle_slit(Slit *s, XEvent *e);
+static void event_handle_slitapp(SlitApp *app, XEvent *e);
static void event_handle_client(Client *c, XEvent *e);
static void event_handle_menu(Menu *menu, XEvent *e);
XNextEvent(ob_display, &e);
event_process(&e);
- had_event = TRUE;
+ had_event = TRUE;
}
if (!had_event) {
case ConfigureRequest:
window = e->xconfigurerequest.window;
break;
+ case ConfigureNotify:
+ window = e->xconfigure.window;
+ break;
default:
#ifdef XKB
if (extensions_xkb && e->type == extensions_xkb_event_basep) {
e->xfocus.window, e->xfocus.mode, e->xfocus.detail);
#endif
- /* Try process a FocusIn first, and if a legit one isn't found, then
- do the fallback shiznit. */
{
XEvent fe;
gboolean fallback = TRUE;
while (TRUE) {
- if (!XCheckTypedEvent(ob_display, FocusOut, &fe))
+ if (!XCheckTypedWindowEvent(ob_display, FocusOut,
+ e->xfocus.window,&fe))
if (!XCheckTypedEvent(ob_display, FocusIn, &fe))
break;
if (fe.type == FocusOut) {
#ifdef DEBUG_FOCUS
g_message("found pending FocusIn");
#endif
+ /* is the focused window getting a FocusOut/In back to
+ itself? */
+ if (fe.xfocus.window == e->xfocus.window &&
+ !event_ignore(&fe, client)) {
+#ifdef DEBUG_FOCUS
+ g_message("focused window got an Out/In back to "
+ "itself IGNORED both");
+#endif
+ return TRUE;
+ }
+
/* 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);
if (e->xcrossing.mode == NotifyGrab ||
e->xcrossing.detail == NotifyInferior ||
(e->xcrossing.mode == NotifyUngrab &&
- e->xcrossing.detail == NotifyVirtual))
+ e->xcrossing.detail == NotifyVirtual)) {
+#ifdef DEBUG_FOCUS
+ g_message("%sNotify mode %d detail %d on %lx IGNORED",
+ (e->type == EnterNotify ? "Enter" : "Leave"),
+ e->xcrossing.mode,
+ e->xcrossing.detail, client?client->window:0);
+#endif
return TRUE;
+ }
+#ifdef DEBUG_FOCUS
+ g_message("%sNotify mode %d detail %d on %lx",
+ (e->type == EnterNotify ? "Enter" : "Leave"),
+ e->xcrossing.mode,
+ e->xcrossing.detail, client?client->window:0);
+#endif
break;
}
return FALSE;
static void event_process(XEvent *e)
{
Window window;
- Client *client;
+ Client *client = NULL;
+ Slit *slit = NULL;
+ SlitApp *slitapp = NULL;
Menu *menu = NULL;
window = event_get_window(e);
if (!(client = g_hash_table_lookup(client_map, &window)))
- menu = g_hash_table_lookup(menu_map, &window);
+ if (!(slitapp = g_hash_table_lookup(slit_app_map, &window)))
+ if (!(slit = g_hash_table_lookup(slit_map, &window)))
+ menu = g_hash_table_lookup(menu_map, &window);
+
event_set_lasttime(e);
event_hack_mods(e);
if (event_ignore(e, client))
return;
} else if (client)
event_handle_client(client, e);
+ else if (slitapp)
+ event_handle_slitapp(slitapp, e);
+ else if (slit)
+ event_handle_slit(slit, e);
else if (window == ob_root)
event_handle_root(e);
else if (e->type == MapRequest)
e->type == ButtonPress ||
e->type == KeyPress || e->type == KeyRelease) {
moveresize_event(e);
+
return; /* no dispatch! */
+
}
/* user input (action-bound) events */
else if (e->xproperty.atom == prop_atoms.net_desktop_layout)
screen_update_layout();
break;
+ case ConfigureNotify:
+#ifdef XRANDR
+ XRRUpdateConfiguration(e);
+#endif
+ if (e->xconfigure.width != screen_physical_size.width ||
+ e->xconfigure.height != screen_physical_size.height)
+ screen_resize(e->xconfigure.width, e->xconfigure.height);
+ break;
+ default:
+ ;
+#ifdef VIDMODE
+ if (extensions_vidmode && e->type == extensions_vidmode_event_basep) {
+ g_message("VIDMODE EVENT");
+ }
+#endif
}
}
}
break;
case FocusIn:
+#ifdef DEBUG_FOCUS
+ g_message("FocusIn on client for %lx", client->window);
+#endif
focus_set_client(client);
+ frame_adjust_focus(client->frame, TRUE);
+ break;
case FocusOut:
#ifdef DEBUG_FOCUS
- g_message("Focus%s on client for %lx", (e->type==FocusIn?"In":"Out"),
- client->window);
+ g_message("FocusOut on client for %lx", client->window);
#endif
- /* focus state can affect the stacking layer */
- client_calc_layer(client);
- frame_adjust_focus(client->frame);
+ /* are we a fullscreen window or a transient of one? (checks layer)
+ if we are then we need to be iconified since we are losing focus
+ */
+ if (client->layer == Layer_Fullscreen && !client->iconic &&
+ !client_search_focus_tree_full(client))
+ /* iconify fullscreen windows when they and their transients
+ aren't focused */
+ client_iconify(client, TRUE, TRUE);
+ frame_adjust_focus(client->frame, FALSE);
break;
case EnterNotify:
if (client_normal(client)) {
client_close(client);
} else if (msgtype == prop_atoms.net_active_window) {
g_message("net_active_window for 0x%lx", client->window);
- if (screen_showing_desktop)
- screen_show_desktop(FALSE);
- if (client->iconic)
- client_iconify(client, FALSE, TRUE);
- else if (!client->frame->visible)
- /* if its not visible for other reasons, then don't mess
- with it */
- break;
- if (client->shaded)
- client_shade(client, FALSE);
- client_focus(client);
- stacking_raise(client);
+ client_activate(client);
} else if (msgtype == prop_atoms.net_wm_moveresize) {
g_message("net_wm_moveresize for 0x%lx", client->window);
if ((Atom)e->xclient.data.l[2] ==
client_setup_decor_and_functions(client);
}
else if (msgtype == prop_atoms.net_wm_name ||
- msgtype == prop_atoms.wm_name)
- client_update_title(client);
- else if (msgtype == prop_atoms.net_wm_icon_name ||
+ msgtype == prop_atoms.wm_name ||
+ msgtype == prop_atoms.net_wm_icon_name ||
msgtype == prop_atoms.wm_icon_name)
- client_update_icon_title(client);
+ client_update_title(client);
else if (msgtype == prop_atoms.wm_class)
client_update_class(client);
else if (msgtype == prop_atoms.wm_protocols) {
g_message("EVENT %d", e->type);
switch (e->type) {
case ButtonPress:
+ g_message("BUTTON PRESS");
if (e->xbutton.button == 3)
menu_hide(menu);
break;
case ButtonRelease:
+ g_message("BUTTON RELEASED");
if (!menu->shown) break;
/* grab_pointer_window(FALSE, None, menu->frame);*/
e->xbutton.y < (signed)(h+b)) {
menu_entry_fire(entry);
}
- }
+
break;
case EnterNotify:
case LeaveNotify:
g_message("enter/leave");
entry = menu_find_entry(menu, e->xcrossing.window);
if (entry) {
- entry->hilite = e->type == EnterNotify;
+ if (menu->mouseover)
+ menu->mouseover(entry, e->type == EnterNotify);
+ else
+ menu_control_mouseover(entry, e->type == EnterNotify);
+
menu_entry_render(entry);
}
break;
+ }
+ }
+}
+
+static void event_handle_slit(Slit *s, XEvent *e)
+{
+ switch (e->type) {
+ case EnterNotify:
+ slit_hide(s, FALSE);
+ break;
+ case LeaveNotify:
+ slit_hide(s, TRUE);
+ break;
+ }
+}
+
+static void event_handle_slitapp(SlitApp *app, XEvent *e)
+{
+ switch (e->type) {
+ case UnmapNotify:
+ if (app->ignore_unmaps) {
+ app->ignore_unmaps--;
+ break;
+ }
+ slit_remove(app, TRUE);
+ break;
+ case DestroyNotify:
+ slit_remove(app, FALSE);
+ break;
+ case ReparentNotify:
+ slit_remove(app, FALSE);
+ break;
+ case ConfigureNotify:
+ slit_app_configure(app, e->xconfigure.width, e->xconfigure.height);
+ break;
}
}