#include "openbox.h"
-#include "slit.h"
+#include "dock.h"
#include "client.h"
#include "xerror.h"
#include "prop.h"
#include <X11/Xatom.h>
#include <glib.h>
+#ifdef USE_LIBSN
+# include <libsn/sn.h>
+#endif
+
#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_slit(Slit *s, XEvent *e);
-static void event_handle_slitapp(SlitApp *app, 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, XEvent *e);
+static void event_handle_menu(Menu *menu, Client *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 || \
(e)->xfocus.detail > NotifyNonlinearVirtual)
#define INVALID_FOCUSOUT(e) ((e)->xfocus.mode == NotifyGrab || \
(e)->xfocus.detail == NotifyInferior || \
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);
}
}
XNextEvent(ob_display, &e);
+#ifdef USE_LIBSN
+ sn_display_process_event(ob_sn_display, &e);
+#endif
+
event_process(&e);
had_event = TRUE;
}
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();
}
}
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");
+#endif
+ return TRUE;
+ } else {
+ event_process(&fe);
#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 but focus_client was null "
+ "IGNORED just the Out");
#endif
- return TRUE;
+ return TRUE;
+ }
}
/* once all the FocusOut's have been dealt with, if there
{
Window window;
Client *client = NULL;
- Slit *slit = NULL;
- SlitApp *slitapp = NULL;
+ Dock *dock = NULL;
+ DockApp *dockapp = NULL;
Menu *menu = NULL;
+ ObWindow *obwin = NULL;
window = event_get_window(e);
- if (!(client = g_hash_table_lookup(client_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);
+ 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_Menu:
+ menu = WINDOW_AS_MENU(obwin);
+ break;
+ case Window_Client:
+ client = WINDOW_AS_CLIENT(obwin);
+ break;
+ case Window_Internal:
+ /* not to be used for events */
+ g_assert_not_reached();
+ break;
+ }
+ }
event_set_lasttime(e);
event_hack_mods(e);
/* deal with it in the kernel */
if (menu) {
- event_handle_menu(menu, e);
+ event_handle_menu(menu, client, e);
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 (dockapp)
+ event_handle_dockapp(dockapp, e);
+ else if (dock)
+ event_handle_dock(dock, e);
else if (window == ob_root)
event_handle_root(e);
else if (e->type == MapRequest)
switch (e->type) {
case ButtonPress:
case ButtonRelease:
- switch (frame_context(client, e->xbutton.window)) {
- case Context_Maximize:
- client->frame->max_press = (e->type == ButtonPress);
- framerender_frame(client->frame);
- break;
- case Context_Close:
- client->frame->close_press = (e->type == ButtonPress);
- framerender_frame(client->frame);
- break;
- case Context_Iconify:
- client->frame->iconify_press = (e->type == ButtonPress);
- framerender_frame(client->frame);
- break;
- case Context_AllDesktops:
- client->frame->desk_press = (e->type == ButtonPress);
- framerender_frame(client->frame);
- break;
- case Context_Shade:
- client->frame->shade_press = (e->type == ButtonPress);
- framerender_frame(client->frame);
- break;
- default:
- /* nothing changes with clicks for any other contexts */
- break;
+ /* 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)) {
+ case Context_Maximize:
+ client->frame->max_press = (e->type == ButtonPress);
+ framerender_frame(client->frame);
+ break;
+ case Context_Close:
+ client->frame->close_press = (e->type == ButtonPress);
+ framerender_frame(client->frame);
+ break;
+ case Context_Iconify:
+ client->frame->iconify_press = (e->type == ButtonPress);
+ framerender_frame(client->frame);
+ break;
+ case Context_AllDesktops:
+ client->frame->desk_press = (e->type == ButtonPress);
+ framerender_frame(client->frame);
+ break;
+ case Context_Shade:
+ client->frame->shade_press = (e->type == ButtonPress);
+ framerender_frame(client->frame);
+ break;
+ default:
+ /* nothing changes with clicks for any other contexts */
+ break;
+ }
}
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);
+ if (client != focus_client) {
+ focus_set_client(client);
+ frame_adjust_focus(client->frame, TRUE);
+ }
break;
case FocusOut:
#ifdef DEBUG_FOCUS
corner = 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 if (msgtype == prop_atoms.net_wm_strut)
client_update_strut(client);
- else if (msgtype == prop_atoms.net_wm_icon)
+ else if (msgtype == prop_atoms.net_wm_icon ||
+ msgtype == prop_atoms.kwm_win_icon)
client_update_icons(client);
- else if (msgtype == prop_atoms.kwm_win_icon)
- client_update_kwm_icon(client);
default:
;
#ifdef SHAPE
}
}
-static void event_handle_menu(Menu *menu, XEvent *e)
+static void event_handle_menu(Menu *menu, Client *client, XEvent *e)
{
MenuEntry *entry;
/* grab_pointer_window(FALSE, None, menu->frame);*/
- 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);
+ 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);
+ }
}
}
}
}
-static void event_handle_slit(Slit *s, XEvent *e)
-{
- switch (e->type) {
- case ButtonPress:
- stacking_raise(SLIT_AS_WINDOW(s));
- case EnterNotify:
- slit_hide(s, FALSE);
- break;
- case LeaveNotify:
- slit_hide(s, TRUE);
- 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);
}
-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);
}
+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);
+ 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_slitapp(SlitApp *app, XEvent *e)
+static void event_handle_dock(Dock *s, XEvent *e)
+{
+ switch (e->type) {
+ case ButtonPress:
+ stacking_raise(DOCK_AS_WINDOW(s));
+ break;
+ case EnterNotify:
+ dock_hide(FALSE);
+ break;
+ case LeaveNotify:
+ dock_hide(TRUE);
+ break;
+ }
+}
+
+static void event_handle_dockapp(DockApp *app, XEvent *e)
{
switch (e->type) {
case MotionNotify:
- slit_app_drag(app, &e->xmotion);
+ dock_app_drag(app, &e->xmotion);
break;
case UnmapNotify:
if (app->ignore_unmaps) {
app->ignore_unmaps--;
break;
}
- slit_remove(app, TRUE);
+ dock_remove(app, TRUE);
break;
case DestroyNotify:
- slit_remove(app, FALSE);
+ dock_remove(app, FALSE);
break;
case ReparentNotify:
- slit_remove(app, FALSE);
+ dock_remove(app, FALSE);
break;
case ConfigureNotify:
- slit_app_configure(app, e->xconfigure.width, e->xconfigure.height);
+ dock_app_configure(app, e->xconfigure.width, e->xconfigure.height);
break;
}
}