#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#ifdef USE_SM
+#include <X11/ICE/ICElib.h>
+#endif
static void event_process(XEvent *e);
static void event_handle_root(XEvent *e);
-static void event_handle_dock(Dock *s, XEvent *e);
-static void event_handle_dockapp(DockApp *app, XEvent *e);
-static void event_handle_client(Client *c, XEvent *e);
-static void event_handle_menu(Menu *menu, Client *c, XEvent *e);
+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_menu(ObClient *c, XEvent *e);
+static void fd_event_handle();
+#ifdef USE_SM
+static void ice_watch(IceConn conn, IcePointer data, Bool opening,
+ IcePointer *watch_data);
+#endif
+static void find_max_fd();
#define INVALID_FOCUSIN(e) ((e)->xfocus.detail == NotifyInferior || \
(e)->xfocus.detail == NotifyAncestor || \
static int mask_table_size;
static fd_set selset, allset;
+#ifdef USE_SM
+static IceConn ice_conn;
+static int ice_fd;
+#endif
static int max_fd, x_fd;
static GData *fd_handler_list;
-void fd_event_handle();
+
+#ifdef USE_SM
+static void ice_watch(IceConn conn, IcePointer data, Bool opening,
+ IcePointer *watch_data)
+{
+ if (opening) {
+ g_assert (ice_fd < 0);
+ ice_conn = conn;
+ ice_fd = IceConnectionNumber(conn);
+ FD_SET(ice_fd, &allset);
+ } else {
+ FD_CLR(ice_fd, &allset);
+ ice_fd = -1;
+ }
+ find_max_fd();
+}
+#endif
void event_startup()
{
FD_ZERO(&allset);
max_fd = x_fd = ConnectionNumber(ob_display);
FD_SET(x_fd, &allset);
+
+#ifdef USE_SM
+ ice_fd = -1;
+ IceAddConnectionWatch(ice_watch, NULL);
+#endif
+
g_datalist_init(&fd_handler_list);
}
struct timeval *wait;
gboolean had_event = FALSE;
- while (TRUE) {
- /*
- There are slightly different event retrieval semantics here for
- local (or high bandwidth) versus remote (or low bandwidth)
- connections to the display/Xserver.
- */
- if (ob_remote) {
- if (!XPending(ob_display))
- break;
- } else {
- /*
- This XSync allows for far more compression of events, which
- makes things like Motion events perform far far better. Since
- it also means network traffic for every event instead of every
- X events (where X is the number retrieved at a time), it
- probably should not be used for setups where Openbox is
- running on a remote/low bandwidth display/Xserver.
- */
- XSync(ob_display, FALSE);
- if (!XEventsQueued(ob_display, QueuedAlready))
- break;
- }
+ while (XPending(ob_display)) {
XNextEvent(ob_display, &e);
#ifdef USE_LIBSN
if (FD_ISSET(x_fd, &selset))
return;
+#ifdef USE_SM
+ if (ice_fd >= 0 && FD_ISSET(ice_fd, &selset)) {
+ Bool b;
+ IceProcessMessages(ice_conn, NULL, &b);
+ }
+#endif
+
fd_event_handle();
}
}
}
}
-static gboolean event_ignore(XEvent *e, Client *client)
+static gboolean event_ignore(XEvent *e, ObClient *client)
{
switch(e->type) {
case FocusIn:
g_message("found pending FocusIn");
#endif
/* is the focused window getting a FocusOut/In back to
- itself? */
+ itself?
+ */
if (fe.xfocus.window == e->xfocus.window &&
!event_ignore(&fe, client)) {
+ /*
+ if focus_client is not set, then we can't do
+ this. we need the FocusIn. This happens in the
+ case when the set_focus_client(NULL) in the
+ focus_fallback function fires and then
+ focus_fallback picks the currently focused
+ window (such as on a SendToDesktop-esque action.
+ */
+ if (focus_client) {
#ifdef DEBUG_FOCUS
- g_message("focused window got an Out/In back to "
- "itself IGNORED both");
+ g_message("focused window got an Out/In back to "
+ "itself IGNORED both");
#endif
- return TRUE;
+ return TRUE;
+ } else {
+ event_process(&fe);
+#ifdef DEBUG_FOCUS
+ g_message("focused window got an Out/In back to "
+ "itself but focus_client was null "
+ "IGNORED just the Out");
+#endif
+ return TRUE;
+ }
}
/* once all the FocusOut's have been dealt with, if there
g_message("no valid FocusIn and no FocusOut events found, "
"falling back");
#endif
- focus_fallback(Fallback_NoFocus);
+ focus_fallback(OB_FOCUS_FALLBACK_NOFOCUS);
}
}
break;
static void event_process(XEvent *e)
{
Window window;
- Client *client = NULL;
- Dock *dock = NULL;
- DockApp *dockapp = NULL;
+ ObClient *client = NULL;
+ ObDock *dock = NULL;
+ ObDockApp *dockapp = NULL;
Menu *menu = NULL;
ObWindow *obwin = NULL;
return;
/* deal with it in the kernel */
- if (menu) {
- event_handle_menu(menu, client, e);
- return;
- } else if (client)
+ if (client)
event_handle_client(client, e);
else if (dockapp)
event_handle_dockapp(dockapp, e);
else if (dock)
event_handle_dock(dock, e);
- else if (window == ob_root)
+ else if (window == RootWindow(ob_display, ob_screen))
event_handle_root(e);
else if (e->type == MapRequest)
client_manage(window);
xerror_set_ignore(FALSE);
}
+ if (menu_visible)
+ if (e->type == MotionNotify || e->type == ButtonRelease ||
+ e->type == ButtonPress ||
+ e->type == KeyPress || e->type == KeyRelease) {
+ event_handle_menu(client, e);
+
+ return; /* no dispatch! */
+ }
+
if (moveresize_in_progress)
if (e->type == MotionNotify || e->type == ButtonRelease ||
e->type == ButtonPress ||
#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);
+ screen_resize();
break;
default:
;
}
}
-static void event_handle_client(Client *client, XEvent *e)
+static void event_handle_client(ObClient *client, XEvent *e)
{
XEvent ce;
Atom msgtype;
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)) {
- case Context_Maximize:
+ case OB_FRAME_CONTEXT_MAXIMIZE:
client->frame->max_press = (e->type == ButtonPress);
framerender_frame(client->frame);
break;
- case Context_Close:
+ case OB_FRAME_CONTEXT_CLOSE:
client->frame->close_press = (e->type == ButtonPress);
framerender_frame(client->frame);
break;
- case Context_Iconify:
+ case OB_FRAME_CONTEXT_ICONIFY:
client->frame->iconify_press = (e->type == ButtonPress);
framerender_frame(client->frame);
break;
- case Context_AllDesktops:
+ case OB_FRAME_CONTEXT_ALLDESKTOPS:
client->frame->desk_press = (e->type == ButtonPress);
framerender_frame(client->frame);
break;
- case Context_Shade:
+ case OB_FRAME_CONTEXT_SHADE:
client->frame->shade_press = (e->type == ButtonPress);
framerender_frame(client->frame);
break;
/* 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 &&
+ if (client->layer == OB_STACKING_LAYER_FULLSCREEN && !client->iconic &&
!client_search_focus_tree_full(client))
/* iconify fullscreen windows when they and their transients
aren't focused */
break;
case EnterNotify:
if (client_normal(client)) {
- if (ob_state == State_Starting) {
+ if (ob_state() == OB_STATE_STARTING) {
/* move it to the top of the focus order */
guint desktop = client->desktop;
if (desktop == DESKTOP_ALL) desktop = screen_desktop;
if (e->xconfigurerequest.value_mask & (CWWidth | CWHeight |
CWX | CWY)) {
int x, y, w, h;
- Corner corner;
+ ObCorner corner;
x = (e->xconfigurerequest.value_mask & CWX) ?
e->xconfigurerequest.x : client->area.x;
switch (client->gravity) {
case NorthEastGravity:
case EastGravity:
- corner = Corner_TopRight;
+ corner = OB_CORNER_TOPRIGHT;
break;
case SouthWestGravity:
case SouthGravity:
- corner = Corner_BottomLeft;
+ corner = OB_CORNER_BOTTOMLEFT;
break;
case SouthEastGravity:
- corner = Corner_BottomRight;
+ corner = OB_CORNER_BOTTOMRIGHT;
break;
default: /* NorthWest, Static, etc */
- corner = Corner_TopLeft;
+ corner = OB_CORNER_TOPLEFT;
}
- client_configure(client, corner, x, y, w, h, FALSE, FALSE);
+ client_configure(client, corner, x, y, w, h, FALSE, TRUE);
}
if (e->xconfigurerequest.value_mask & CWStackMode) {
else
h = client->area.y;
client->gravity = tmpg;
- client_configure(client, Corner_TopLeft, x, y, w, h, TRUE, TRUE);
+ client_configure(client, OB_CORNER_TOPLEFT,
+ x, y, w, h, FALSE, TRUE);
client->gravity = oldg;
}
break;
}
}
-static void event_handle_menu(Menu *menu, Client *client, XEvent *e)
+static void event_handle_menu(ObClient *client, XEvent *e)
{
+ static MenuEntry *over = NULL;
MenuEntry *entry;
+ Menu *top;
+ GSList *it;
+
+ top = g_slist_nth_data(menu_visible, 0);
g_message("EVENT %d", e->type);
switch (e->type) {
+ case KeyPress:
+ if (over) {
+ if (over->parent->mouseover)
+ over->parent->mouseover(over, FALSE);
+ else
+ menu_control_mouseover(over, FALSE);
+ menu_entry_render(over);
+ over = NULL;
+ }
+/*
+ if (top->hide)
+ top->hide(top);
+ else
+*/
+ menu_hide(top);
+ break;
case ButtonPress:
+ if (e->xbutton.button > 3) break;
+
g_message("BUTTON PRESS");
- if (e->xbutton.button == 3)
- menu_hide(menu);
- else if (e->xbutton.button == 1) {
- entry = menu_find_entry(menu, e->xbutton.window);
- if (!entry)
- stacking_raise(MENU_AS_WINDOW(menu));
- }
break;
case ButtonRelease:
+ if (e->xbutton.button > 3) break;
+
g_message("BUTTON RELEASED");
- if (!menu->shown) break;
-
-/* grab_pointer_window(FALSE, None, menu->frame);*/
-
- if (e->xbutton.button == 1) {
- entry = menu_find_entry(menu, e->xbutton.window);
- if (entry) {
- int junk;
- Window wjunk;
- guint ujunk, b, w, h;
- XGetGeometry(ob_display, e->xbutton.window,
- &wjunk, &junk, &junk, &w, &h, &b, &ujunk);
- if (e->xbutton.x >= (signed)-b &&
- e->xbutton.y >= (signed)-b &&
- e->xbutton.x < (signed)(w+b) &&
- e->xbutton.y < (signed)(h+b)) {
- menu_entry_fire(entry);
+
+ for (it = menu_visible; it; it = g_slist_next(it)) {
+ Menu *m = it->data;
+ if (e->xbutton.x_root >= m->location.x - ob_rr_theme->bwidth &&
+ e->xbutton.y_root >= m->location.y - ob_rr_theme->bwidth &&
+ e->xbutton.x_root < m->location.x + m->size.width +
+ ob_rr_theme->bwidth &&
+ e->xbutton.y_root < m->location.y + m->size.height +
+ ob_rr_theme->bwidth) {
+ if ((entry = menu_find_entry_by_pos(it->data,
+ e->xbutton.x_root -
+ m->location.x,
+ e->xbutton.y_root -
+ m->location.y))) {
+ if (over) {
+ if (over->parent->mouseover)
+ over->parent->mouseover(over, FALSE);
+ else
+ menu_control_mouseover(over, FALSE);
+ menu_entry_render(over);
+ over = NULL;
+ /* this hides the menu */
+ menu_entry_fire(entry);
+ }
}
+ break;
}
}
+ if (!it) {
+ if (over) {
+ if (over->parent->mouseover)
+ over->parent->mouseover(over, FALSE);
+ else
+ menu_control_mouseover(over, FALSE);
+ menu_entry_render(over);
+ over = NULL;
+ }
+/*
+ if (top->hide)
+ top->hide(top);
+ else
+*/
+ menu_hide(top);
+ }
break;
- case EnterNotify:
- case LeaveNotify:
- g_message("enter/leave");
- entry = menu_find_entry(menu, e->xcrossing.window);
- if (entry) {
- if (menu->mouseover)
- menu->mouseover(entry, e->type == EnterNotify);
+ case MotionNotify:
+ g_message("motion");
+ for (it = menu_visible; it; it = g_slist_next(it)) {
+ Menu *m = it->data;
+ if ((entry = menu_find_entry_by_pos(it->data,
+ e->xmotion.x_root -
+ m->location.x,
+ e->xmotion.y_root -
+ m->location.y))) {
+ if (over && entry != over) {
+ if (over->parent->mouseover)
+ over->parent->mouseover(over, FALSE);
+ else
+ menu_control_mouseover(over, FALSE);
+ menu_entry_render(over);
+ }
+
+ over = entry;
+ if (over->parent->mouseover)
+ over->parent->mouseover(over, TRUE);
+ else
+ menu_control_mouseover(over, TRUE);
+ menu_entry_render(over);
+ break;
+ }
+ }
+ if (!it && over) {
+ if (over->parent->mouseover)
+ over->parent->mouseover(over, FALSE);
else
- menu_control_mouseover(entry, e->type == EnterNotify);
-
- menu_entry_render(entry);
+ menu_control_mouseover(over, FALSE);
+ menu_entry_render(over);
+ over = NULL;
}
break;
}
}
void event_add_fd_handler(event_fd_handler *h) {
- g_datalist_id_set_data(&fd_handler_list, h->fd, h);
- FD_SET(h->fd, &allset);
- max_fd = MAX(max_fd, h->fd);
+ g_datalist_id_set_data(&fd_handler_list, h->fd, h);
+ FD_SET(h->fd, &allset);
+ max_fd = MAX(max_fd, h->fd);
}
-void find_max_fd_foreach(GQuark n, gpointer data, gpointer max)
+static void find_max_fd_foreach(GQuark n, gpointer data, gpointer max)
{
- *((unsigned int *)max) = MAX(*((unsigned int *)max), n);
+ *((unsigned int *)max) = MAX(*((unsigned int *)max), n);
+}
+
+static void find_max_fd()
+{
+ int tmpmax = -1;
+ g_datalist_foreach(&fd_handler_list, find_max_fd_foreach,
+ (gpointer)&tmpmax);
+ max_fd = MAX(x_fd, tmpmax);
+#ifdef USE_SM
+ max_fd = MAX(ice_fd, tmpmax);
+#endif
}
void event_remove_fd(int n)
{
- int tmpmax = 0;
- FD_CLR(n, &allset);
- g_datalist_id_remove_data(&fd_handler_list, (GQuark)n);
- g_datalist_foreach(&fd_handler_list, find_max_fd_foreach, (gpointer)&tmpmax);
- max_fd = MAX(x_fd, tmpmax);
+ FD_CLR(n, &allset);
+ g_datalist_id_remove_data(&fd_handler_list, (GQuark)n);
+ find_max_fd();
}
-void fd_event_handle_foreach(GQuark n, gpointer data, gpointer user_data)
+static void fd_event_handle_foreach(GQuark n, gpointer data, gpointer user_data)
{
if (FD_ISSET( (int)n, &selset)) {
event_fd_handler *h = (event_fd_handler *)data;
}
}
-void fd_event_handle()
+static void fd_event_handle()
{
g_datalist_foreach(&fd_handler_list, fd_event_handle_foreach, NULL);
}
-static void event_handle_dock(Dock *s, XEvent *e)
+static void event_handle_dock(ObDock *s, XEvent *e)
{
switch (e->type) {
case ButtonPress:
}
}
-static void event_handle_dockapp(DockApp *app, XEvent *e)
+static void event_handle_dockapp(ObDockApp *app, XEvent *e)
{
switch (e->type) {
case MotionNotify: