diff options
-rw-r--r-- | configure.ac | 28 | ||||
-rw-r--r-- | doc/MBWM2-Overview.xml | 15 | ||||
-rw-r--r-- | managers/clutter/matchbox-window-manager-2-clutter.c | 38 | ||||
-rw-r--r-- | managers/maemo/matchbox-window-manager-2-maemo.c | 2 | ||||
-rw-r--r-- | managers/simple/matchbox-window-manager-2-simple.c | 13 | ||||
-rw-r--r-- | managers/xrender/matchbox-window-manager-2-xrender.c | 15 | ||||
-rw-r--r-- | matchbox/Makefile.am | 2 | ||||
-rw-r--r-- | matchbox/matchbox.h | 1 | ||||
-rw-r--r-- | matchbox/mb-wm-client.c | 11 | ||||
-rw-r--r-- | matchbox/mb-wm-comp-mgr.c | 4 | ||||
-rw-r--r-- | matchbox/mb-wm-config.h.in | 6 | ||||
-rw-r--r-- | matchbox/mb-wm-decor.c | 541 | ||||
-rw-r--r-- | matchbox/mb-wm-decor.h | 3 | ||||
-rw-r--r-- | matchbox/mb-wm-main-context.c | 1116 | ||||
-rw-r--r-- | matchbox/mb-wm-main-context.h | 150 | ||||
-rw-r--r-- | matchbox/mb-wm-manager.c | 991 | ||||
-rw-r--r-- | matchbox/mb-wm-manager.h | 73 | ||||
-rw-r--r-- | matchbox/mb-wm-object.h | 2 | ||||
-rw-r--r-- | matchbox/mb-wm-types.h | 24 |
19 files changed, 1240 insertions, 1795 deletions
diff --git a/configure.ac b/configure.ac index d814d44..3ca9697 100644 --- a/configure.ac +++ b/configure.ac @@ -62,18 +62,10 @@ AC_ARG_WITH(pango, [ --with-pango Use of pango for text layout], [use_pango=$withval], [use_pango=no]) -AC_ARG_WITH(gtk, - [ --with-gtk With GTK integration support], - [use_gtk=$withval], [use_gtk=no]) - AC_ARG_ENABLE(compositing, [ --enable-compositing Enable support for compositing], [compositing=$enableval], [compositing=no]) -AC_ARG_ENABLE(glib-main-loop, - [ --enable-glib-main-loop Enable use of glib main loop], - [gmloop=$enableval], [gmloop=no]) - AC_ARG_ENABLE(matchbox-remote, [ --enable-matchbox-remote Enable matchbox remote control utility], [matchbox_remote=$enableval], [matchbox_remote=no]) @@ -99,10 +91,6 @@ if ! test "x$use_pango" = "xyes" -o "x$use_pango" = "xyes"; then needed_pkgs="$needed_pkgs xft " fi -if test "x$use_gtk" = "xyes"; then - needed_pkgs="$needed_pkgs gtk+-2.0 " -fi - if test "x$png_theme" = "xyes"; then needed_pkgs="$needed_pkgs libpng12 " fi @@ -137,7 +125,6 @@ for manager in $included_managers; do ;; clutter ) needed_pkgs="$needed_pkgs $clutter_package xcomposite xdamage " - gmloop="yes" ;; esac @@ -157,12 +144,6 @@ if test "x$want_debug" = "xyes"; then fi AC_SUBST(MBWM_WANT_DEBUG) -USE_GLIB_MAINLOOP=0 -if test "x$gmloop" = "xyes"; then - USE_GLIB_MAINLOOP=1 -fi -AC_SUBST(USE_GLIB_MAINLOOP) - USE_PANGO=0 if test "$use_pango" = yes; then USE_PANGO=1 @@ -184,13 +165,6 @@ if test "$use_png" != yes; then fi AC_SUBST(THEME_SIMPLE) -USE_GTK=0 -AM_CONDITIONAL(USE_GTK, test "x$use_gtk" = "xyes") -if test "$use_gtk" = yes; then - USE_GTK=1 -fi -AC_SUBST(USE_GTK) - PKG_CHECK_MODULES(MBWM, $needed_pkgs) MBWM_PKGREQUIRES="$MBWM_PKGREQUIRES $needed_pkgs" AC_SUBST(MBWM_PKGREQUIRES) @@ -311,7 +285,6 @@ echo " Themes: PNG theme : ${png_theme} - GTK integration : ${use_gtk} Pango integration : ${use_pango} Managers: @@ -321,7 +294,6 @@ echo " Miscel: Compositing support : ${compositing} - Glib main loop : ${gmloop} Build matchbox-remote : ${matchbox_remote} Debugging output : ${want_debug} " diff --git a/doc/MBWM2-Overview.xml b/doc/MBWM2-Overview.xml index d8c2c6b..afcab2e 100644 --- a/doc/MBWM2-Overview.xml +++ b/doc/MBWM2-Overview.xml @@ -312,21 +312,6 @@ </section> - <section id="MBWMMainContext"> - <title>MBWMMainContext</title> - - <para>MBWMMainContext is an object encapsulating main loop - functionality. It provides API for adding timeouts, custom x-event - handlers and FD watches. - </para> - - <para>Optionally, the MBWMMainContext allows for the use of a GLib main - loop, making it possible to integrate the MBWM2 with other components that - use (and rely on) the GLib main loop. For this functionality, - --enable-glib-main-loop should be used at configure time. - </para> - </section> - <section id="MBWindowManager"> <title>MBWindowManager</title> diff --git a/managers/clutter/matchbox-window-manager-2-clutter.c b/managers/clutter/matchbox-window-manager-2-clutter.c index ab3b227..68d0431 100644 --- a/managers/clutter/matchbox-window-manager-2-clutter.c +++ b/managers/clutter/matchbox-window-manager-2-clutter.c @@ -4,10 +4,6 @@ #include <matchbox/matchbox.h> #include <signal.h> -#if USE_GTK -#include <gdk/gdkx.h> -#endif - enum { KEY_ACTION_PAGE_NEXT, KEY_ACTION_PAGE_PREV, @@ -76,6 +72,15 @@ key_binding_func (MBWMManager *wm, } } +ClutterX11FilterReturn +forward_xevent (XEvent *xevent, + ClutterEvent *event, + void *user_data) +{ + mb_wm_manager_handle_xlib_event (wm, xevent); + return CLUTTER_X11_FILTER_CONTINUE; +} + int main(int argc, char **argv) { @@ -91,35 +96,22 @@ main(int argc, char **argv) mb_wm_object_init(); -#if USE_GTK - printf ("initializing gtk\n"); - - gtk_init (&argc, &argv); - dpy = GDK_DISPLAY(); -#endif - - /* - * If using clutter, we share the display connection, and hook - * our xevent handler into the clutter main loop. - * - * If we are also doing gtk integration, we need to make clutter to - * use the gtk display connection. + /* We share Clutter's display connection, and hook our xevent + * handler into the clutter main loop. */ if (dpy) clutter_x11_set_display (dpy); -#if USE_GTK - clutter_x11_disable_event_retrieval (); -#endif - clutter_init (&argc, &argv); if (!dpy) dpy = clutter_x11_get_default_display (); + clutter_x11_add_filter (forward_xevent, wm); + wm = mb_wm_manager_new_with_dpy (argc, argv, dpy); compositor = mb_wm_comp_mgr_clutter_new (wm); - mb_wm_manager_run_with_compositor (wm, compositor); + mb_wm_manager_start_with_compositor (wm, compositor); mb_wm_object_unref (MB_WM_OBJECT (compositor)); if (wm == NULL) @@ -143,7 +135,7 @@ main(int argc, char **argv) NULL, (void*)KEY_ACTION_PAGE_PREV); - mb_wm_manager_main_loop(wm); + clutter_main (); mb_wm_object_unref (MB_WM_OBJECT (wm)); diff --git a/managers/maemo/matchbox-window-manager-2-maemo.c b/managers/maemo/matchbox-window-manager-2-maemo.c index 577a1b2..c24559e 100644 --- a/managers/maemo/matchbox-window-manager-2-maemo.c +++ b/managers/maemo/matchbox-window-manager-2-maemo.c @@ -102,7 +102,7 @@ main(int argc, char **argv) mb_wm_object_init(); wm = maemo_window_manager_new(argc, argv); - mb_wm_manager_run (wm); + mb_wm_manager_start (wm); if (wm == NULL) mb_wm_util_fatal_error("OOM?"); diff --git a/managers/simple/matchbox-window-manager-2-simple.c b/managers/simple/matchbox-window-manager-2-simple.c index 8881895..52445cc 100644 --- a/managers/simple/matchbox-window-manager-2-simple.c +++ b/managers/simple/matchbox-window-manager-2-simple.c @@ -1,10 +1,6 @@ #include <matchbox/matchbox.h> #include <signal.h> -#if USE_GTK -#include <gdk/gdkx.h> -#endif - enum { KEY_ACTION_PAGE_NEXT, KEY_ACTION_PAGE_PREV, @@ -87,15 +83,8 @@ main(int argc, char **argv) mb_wm_object_init(); -#if USE_GTK - printf ("initializing gtk\n"); - - gtk_init (&argc, &argv); - dpy = GDK_DISPLAY(); -#endif - wm = mb_wm_manager_new_with_dpy (argc, argv, dpy); - mb_wm_manager_run (wm); + mb_wm_manager_start (wm); if (wm == NULL) mb_wm_util_fatal_error("OOM?"); diff --git a/managers/xrender/matchbox-window-manager-2-xrender.c b/managers/xrender/matchbox-window-manager-2-xrender.c index 70e6855..cdde66b 100644 --- a/managers/xrender/matchbox-window-manager-2-xrender.c +++ b/managers/xrender/matchbox-window-manager-2-xrender.c @@ -4,10 +4,6 @@ #include <matchbox/matchbox.h> #include <signal.h> -#if USE_GTK -#include <gdk/gdkx.h> -#endif - enum { KEY_ACTION_PAGE_NEXT, KEY_ACTION_PAGE_PREV, @@ -91,19 +87,10 @@ main(int argc, char **argv) mb_wm_object_init(); -#if USE_GTK - printf ("initializing gtk\n"); - - gtk_init (&argc, &argv); - dpy = GDK_DISPLAY(); - - wm = mb_wm_manager_new_with_dpy (argc, argv, dpy); -#else wm = mb_wm_manager_new (argc, argv); -#endif compositor = mb_wm_comp_mgr_xrender_new (wm); - mb_wm_manager_run_with_compositor (wm, compositor); + mb_wm_manager_start_with_compositor (wm, compositor); mb_wm_object_unref (MB_WM_OBJECT (compositor)); if (wm == NULL) diff --git a/matchbox/Makefile.am b/matchbox/Makefile.am index 8ad2c05..f0cb6f9 100644 --- a/matchbox/Makefile.am +++ b/matchbox/Makefile.am @@ -37,8 +37,6 @@ source = \ mb-wm-decor.c \ mb-wm-manager.h \ mb-wm-manager.c \ - mb-wm-main-context.h \ - mb-wm-main-context.c \ xas.h \ xas.c diff --git a/matchbox/matchbox.h b/matchbox/matchbox.h index 0a745eb..0c703b2 100644 --- a/matchbox/matchbox.h +++ b/matchbox/matchbox.h @@ -66,5 +66,4 @@ #include <matchbox/mb-wm-layout.h> #include <matchbox/mb-wm-stack.h> #include <matchbox/mb-wm-manager.h> -#include <matchbox/mb-wm-main-context.h> #endif diff --git a/matchbox/mb-wm-client.c b/matchbox/mb-wm-client.c index 8dd0746..13c1964 100644 --- a/matchbox/mb-wm-client.c +++ b/matchbox/mb-wm-client.c @@ -754,7 +754,6 @@ void mb_wm_client_ping_start (MBWindowManagerClient *client) { MBWMManager * wm = client->wmref; - MBWMMainContext * ctx = wm->main_ctx; MBWMClientWindowProtos protos = client->window->protos; if (!(protos & MBWMClientWindowProtosPing)) @@ -764,9 +763,9 @@ mb_wm_client_ping_start (MBWindowManagerClient *client) return; client->ping_cb_id = - mb_wm_main_context_timeout_handler_add (ctx, client->ping_timeout, - mb_wm_client_ping_timeout_cb, - client); + g_timeout_add (client->ping_timeout, + mb_wm_client_ping_timeout_cb, + client); mb_wm_client_deliver_ping_protocol (client); } @@ -774,12 +773,10 @@ mb_wm_client_ping_start (MBWindowManagerClient *client) void mb_wm_client_ping_stop (MBWindowManagerClient *client) { - MBWMMainContext * ctx = client->wmref->main_ctx; - if (!client->ping_cb_id) return; - mb_wm_main_context_timeout_handler_remove (ctx, client->ping_cb_id); + g_source_remove (client->ping_cb_id); client->ping_cb_id = 0; } diff --git a/matchbox/mb-wm-comp-mgr.c b/matchbox/mb-wm-comp-mgr.c index 4ce51a6..ce69eb8 100644 --- a/matchbox/mb-wm-comp-mgr.c +++ b/matchbox/mb-wm-comp-mgr.c @@ -439,7 +439,7 @@ mb_wm_comp_mgr_turn_on (MBWMCompMgr *mgr) klass->turn_on (mgr); mgr->damage_cb_id = - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, None, wm->damage_event_base + XDamageNotify, (MBWMXEventFunc)klass->handle_damage, @@ -458,7 +458,7 @@ mb_wm_comp_mgr_turn_off (MBWMCompMgr *mgr) MBWM_ASSERT (klass->turn_off != NULL); klass->turn_off (mgr); - mb_wm_main_context_x_event_handler_remove (wm->main_ctx, + mb_wm_manager_remove_event_handler (wm, wm->damage_event_base + XDamageNotify, mgr->damage_cb_id); diff --git a/matchbox/mb-wm-config.h.in b/matchbox/mb-wm-config.h.in index 8c8de50..4413352 100644 --- a/matchbox/mb-wm-config.h.in +++ b/matchbox/mb-wm-config.h.in @@ -23,12 +23,6 @@ /* Include at least one of the default compositing manager backends */ #define COMP_MGR_BACKEND @COMP_MGR_BACKEND@ -/* Use glib main loop */ -#define USE_GLIB_MAINLOOP @USE_GLIB_MAINLOOP@ - -/* GTK Integration */ -#define USE_GTK @USE_GTK@ - /* Debugging stuff */ #define MBWM_WANT_DEBUG @MBWM_WANT_DEBUG@ diff --git a/matchbox/mb-wm-decor.c b/matchbox/mb-wm-decor.c index 51f674e..74bf664 100644 --- a/matchbox/mb-wm-decor.c +++ b/matchbox/mb-wm-decor.c @@ -192,24 +192,58 @@ mb_wm_decor_resize (MBWMDecor *decor) decor->pack_end_x = btn_x_end; } -static Bool -mb_wm_decor_reparent (MBWMDecor *decor); +typedef struct +{ + MBWMDecor *decor; + int orig_x, orig_y; + int orig_p_x, orig_p_y; +} DecorGrabClosure; static Bool -mb_wm_decor_release_handler (XButtonEvent *xev, - void *userdata) +mb_wm_decor_grab_handler (XEvent *xev, + void *userdata) { - MBWMDecor *decor = userdata; + DecorGrabClosure *closure = userdata; + MBWMDecor *decor = closure->decor; MBWMManager *wm = decor->parent_client->wmref; - mb_wm_main_context_x_event_handler_remove (wm->main_ctx, ButtonRelease, - decor->release_cb_id); + switch (xev->type) + { + case MotionNotify: + { + XMotionEvent *pev = (XMotionEvent*)xev; + MBGeometry geom; - decor->release_cb_id = 0; + int diff_x = pev->x_root - closure->orig_p_x; + int diff_y = pev->y_root - closure->orig_p_y; - XUngrabPointer (wm->xdpy, CurrentTime); + geom.x = closure->orig_x + diff_x; + geom.y = closure->orig_y + diff_y; - return False; + mb_wm_client_request_geometry (decor->parent_client, + &geom, + MBWMClientReqGeomIsViaUserAction); + } + break; + case ButtonRelease: + { + XUngrabPointer (wm->xdpy, CurrentTime); + + mb_wm_manager_remove_event_handler (wm, ButtonRelease, + decor->release_cb_id); + decor->release_cb_id = 0; + mb_wm_manager_remove_event_handler (wm, MotionNotify, + decor->motion_cb_id); + decor->motion_cb_id = 0; + + g_slice_free (DecorGrabClosure, closure); + return False; + } + default: + ; + } + + return True; } static Bool @@ -222,29 +256,6 @@ mb_wm_decor_press_handler (XButtonEvent *xev, if (xev->window == decor->xwin) { - XEvent ev; - MBGeometry geom; - int orig_x, orig_y; - int orig_p_x, orig_p_y; - - mb_wm_client_get_coverage (decor->parent_client, &geom); - - orig_x = geom.x; - orig_y = geom.y; - orig_p_x = xev->x_root; - orig_p_y = xev->y_root; - - /* - * This is bit tricky: we do a normal pointer drag and pull out any - * pointer events out of the queue; when we get a MotionEvent, we - * move the client window. However, for the move to propagete on screen - * (particularly with a compositor) we need to spin the main loop so - * that any queued up ConfigureNotify events get processed; - * unfortunately, this invariably results in the ButtonRelease event - * landing in the main loop and not in our sub-loop here. So, on the - * ButtonPress we install a ButtonRelease callback into the main loop - * and use that to release the grab. - */ if (XGrabPointer(wm->xdpy, xev->subwindow, False, ButtonPressMask|ButtonReleaseMask| PointerMotionMask|EnterWindowMask|LeaveWindowMask, @@ -252,64 +263,29 @@ mb_wm_decor_press_handler (XButtonEvent *xev, GrabModeAsync, None, None, CurrentTime) == GrabSuccess) { + DecorGrabClosure *closure = g_slice_new (DecorGrabClosure); + MBGeometry geom; + + mb_wm_client_get_coverage (decor->parent_client, &geom); - decor->release_cb_id = mb_wm_main_context_x_event_handler_add ( - wm->main_ctx, + closure->decor = decor; + closure->orig_x = geom.x; + closure->orig_y = geom.y; + closure->orig_p_x = xev->x_root; + closure->orig_p_y = xev->y_root; + + decor->release_cb_id = mb_wm_manager_add_event_handler ( + wm, decor->xwin, ButtonRelease, - (MBWMXEventFunc)mb_wm_decor_release_handler, - decor); - - for (;;) - { - /* - * If we have no release_cb installed, i.e., the ButtonRelease - * has already happened, quit this loop. - */ - if (!decor->release_cb_id) - break; - - XMaskEvent(wm->xdpy, - ButtonPressMask|ButtonReleaseMask| - PointerMotionMask|EnterWindowMask| - LeaveWindowMask, - &ev); - - switch (ev.type) - { - case MotionNotify: - { - Bool events_pending; - int event_count = 5; /*Limit how much we spin the loop*/ - XMotionEvent *pev = (XMotionEvent*)&ev; - int diff_x = pev->x_root - orig_p_x; - int diff_y = pev->y_root - orig_p_y; - - geom.x = orig_x + diff_x; - geom.y = orig_y + diff_y; - - mb_wm_client_request_geometry (decor->parent_client, - &geom, - MBWMClientReqGeomIsViaUserAction); - - do - { - events_pending = - mb_wm_main_context_spin_loop (wm->main_ctx); - - --event_count; - } while (events_pending && event_count); - } - break; - case ButtonRelease: - { - XUngrabPointer (wm->xdpy, CurrentTime); - return False; - } - default: - ; - } - } + (MBWMXEventFunc)mb_wm_decor_grab_handler, + closure); + decor->motion_cb_id = mb_wm_manager_add_event_handler ( + wm, + decor->xwin, + MotionNotify, + (MBWMXEventFunc)mb_wm_decor_grab_handler, + closure); } } @@ -317,6 +293,9 @@ mb_wm_decor_press_handler (XButtonEvent *xev, } static Bool +mb_wm_decor_reparent (MBWMDecor *decor); + +static Bool mb_wm_decor_sync_window (MBWMDecor *decor) { MBWMManager *wm; @@ -373,7 +352,7 @@ mb_wm_decor_sync_window (MBWMDecor *decor) decor->parent_client->layout_hints & LayoutPrefMovable) { decor->press_cb_id = - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, decor->xwin, ButtonPress, (MBWMXEventFunc)mb_wm_decor_press_handler, @@ -641,7 +620,7 @@ mb_wm_decor_destroy (MBWMObject* obj) { MBWMDecor * decor = MB_WM_DECOR(obj); GList * l = decor->buttons; - MBWMMainContext * ctx = decor->parent_client->wmref->main_ctx; + MBWMManager * wm = decor->parent_client->wmref; if (decor->themedata && decor->destroy_themedata) { @@ -661,8 +640,19 @@ mb_wm_decor_destroy (MBWMObject* obj) } if (decor->press_cb_id) - mb_wm_main_context_x_event_handler_remove (ctx, ButtonPress, - decor->press_cb_id); + mb_wm_manager_remove_event_handler (wm, ButtonPress, decor->press_cb_id); + + if (decor->release_cb_id) + mb_wm_manager_remove_event_handler (wm, ButtonRelease, decor->release_cb_id); + + if (decor->motion_cb_id) + mb_wm_manager_remove_event_handler (wm, MotionNotify, decor->motion_cb_id); + + if (decor->enter_cb_id) + mb_wm_manager_remove_event_handler (wm, EnterNotify, decor->enter_cb_id); + + if (decor->leave_cb_id) + mb_wm_manager_remove_event_handler (wm, LeaveNotify, decor->leave_cb_id); } void @@ -741,6 +731,101 @@ mb_wm_decor_button_get_theme_data (MBWMDecorButton * button) } static Bool +button_grab_handler (XEvent *xev, void *userdata) +{ + MBWMDecorButton *button = userdata; + MBWMDecor *decor = button->decor; + MBWMManager *wm = decor->parent_client->wmref; + int xmin, ymin, xmax, ymax; + + xmin = button->geom.x; + ymin = button->geom.y; + xmax = button->geom.x + button->geom.width; + ymax = button->geom.y + button->geom.height; + + switch (xev->type) + { + case MotionNotify: + { + XMotionEvent *pev = (XMotionEvent*)xev; + + if (pev->x < xmin || pev->x > xmax || + pev->y < ymin || pev->y > ymax) + { + if (button->state == MBWMDecorButtonStatePressed) + { + button->state = + MBWMDecorButtonStateInactive; + mb_wm_theme_paint_button (wm->theme,button); + } + } + else + { + if (button->state != MBWMDecorButtonStatePressed) + { + button->state = MBWMDecorButtonStatePressed; + mb_wm_theme_paint_button (wm->theme,button); + } + } + } + break; + case EnterNotify: + if (button->state == MBWMDecorButtonStateInactive) + { + button->state = MBWMDecorButtonStatePressed; + mb_wm_theme_paint_button (wm->theme, button); + } + break; + case LeaveNotify: + if (button->state != MBWMDecorButtonStateInactive) + { + button->state = MBWMDecorButtonStateInactive; + mb_wm_theme_paint_button (wm->theme, button); + } + break; + case ButtonRelease: + { + XButtonEvent *pev = (XButtonEvent*)xev; + + if (button->state != MBWMDecorButtonStateInactive) + { + button->state = MBWMDecorButtonStateInactive; + mb_wm_theme_paint_button (wm->theme, button); + } + + XUngrabPointer (wm->xdpy, CurrentTime); + XSync (wm->xdpy, False); /* necessary */ + + if (pev->x < xmin || pev->x > xmax || + pev->y < ymin || pev->y > ymax) + return False; + + if (button->release) + button->release(wm, button, button->userdata); + else + mb_wm_decor_button_stock_button_action (button); + + mb_wm_manager_remove_event_handler (wm, MotionNotify, + decor->motion_cb_id); + decor->motion_cb_id = 0; + mb_wm_manager_remove_event_handler (wm, EnterNotify, + decor->enter_cb_id); + decor->enter_cb_id = 0; + mb_wm_manager_remove_event_handler (wm, LeaveNotify, + decor->leave_cb_id); + decor->leave_cb_id = 0; + mb_wm_manager_remove_event_handler (wm, ButtonRelease, + decor->release_cb_id); + decor->release_cb_id = 0; + + return False; + } + } + + return True; +} + +static Bool mb_wm_decor_button_press_handler (XButtonEvent *xev, void *userdata) { @@ -749,193 +834,116 @@ mb_wm_decor_button_press_handler (XButtonEvent *xev, MBWMManager *wm = decor->parent_client->wmref; GList *l = NULL; Bool retval = True; + int xmin, ymin, xmax, ymax; - if (xev->window == decor->xwin) - { - int xmin, ymin, xmax, ymax; - l = mb_wm_client_get_transients (decor->parent_client); + if (xev->window != decor->xwin) + return True; - /* Ignore events on the main window decor if transients other than - * input methods are present - */ - while (l) - { - MBWindowManagerClient * c = l->data; + l = mb_wm_client_get_transients (decor->parent_client); - if (MB_WM_CLIENT_CLIENT_TYPE (c) != MBWMClientTypeInput && - mb_wm_client_is_modal (c)) - { - retval = True; - goto done; - } + /* Ignore events on the main window decor if transients other than + * input methods are present + */ + while (l) + { + MBWindowManagerClient * c = l->data; - l = l->next; - } + if (MB_WM_CLIENT_CLIENT_TYPE (c) != MBWMClientTypeInput && + mb_wm_client_is_modal (c)) + { + g_list_free (l); + return True; + } - xmin = button->geom.x; - ymin = button->geom.y; - xmax = button->geom.x + button->geom.width; - ymax = button->geom.y + button->geom.height; + l = l->next; + } + g_list_free (l); - if (xev->x < xmin || - xev->x > xmax || - xev->y < ymin || - xev->y > ymax) - { - retval = True; - goto done; - } + xmin = button->geom.x; + ymin = button->geom.y; + xmax = button->geom.x + button->geom.width; + ymax = button->geom.y + button->geom.height; - if (button->state != MBWMDecorButtonStatePressed) - { - button->state = MBWMDecorButtonStatePressed; - mb_wm_theme_paint_button (wm->theme, button); - } + if (xev->x < xmin || + xev->x > xmax || + xev->y < ymin || + xev->y > ymax) + return True; - if (button->press_activated) - { - XUngrabPointer(wm->xdpy, CurrentTime); + if (button->state != MBWMDecorButtonStatePressed) + { + button->state = MBWMDecorButtonStatePressed; + mb_wm_theme_paint_button (wm->theme, button); + } + + if (button->press_activated) + { + XUngrabPointer(wm->xdpy, CurrentTime); - mb_wm_client_deliver_message (decor->parent_client, - wm->atoms[MBWM_ATOM_MB_GRAB_TRANSFER], - xev->time, - xev->subwindow, - xev->button, 0, 0); + mb_wm_client_deliver_message (decor->parent_client, + wm->atoms[MBWM_ATOM_MB_GRAB_TRANSFER], + xev->time, + xev->subwindow, + xev->button, 0, 0); - XSync (wm->xdpy, False); /* Necessary */ + XSync (wm->xdpy, False); /* Necessary */ - if (button->press) - button->press(wm, button, button->userdata); - else - mb_wm_decor_button_stock_button_action (button); - } + if (button->press) + button->press(wm, button, button->userdata); else - { - XEvent ev; + mb_wm_decor_button_stock_button_action (button); + } + else + { + XEvent ev; - /* - * First, call the custom function if any. - */ - if (button->press) - button->press(wm, button, button->userdata); - - if (XGrabPointer(wm->xdpy, xev->subwindow, False, - ButtonPressMask|ButtonReleaseMask| - PointerMotionMask|EnterWindowMask|LeaveWindowMask, - GrabModeAsync, - GrabModeAsync, - None, None, CurrentTime) == GrabSuccess) - { - if (button->state == MBWMDecorButtonStateInactive) - { - button->state = MBWMDecorButtonStatePressed; - mb_wm_theme_paint_button (wm->theme, button); - } - - for (;;) - { - /* - * First of all, we make sure that all events are flushed - * out (this is necessary to ensure that all the events we - * are interested in are actually intercepted here). - */ - XSync (wm->xdpy, False); - - if (XCheckMaskEvent(wm->xdpy, - ButtonPressMask|ButtonReleaseMask| - PointerMotionMask|EnterWindowMask| - LeaveWindowMask, - &ev)) - { - switch (ev.type) - { - case MotionNotify: - { - XMotionEvent *pev = (XMotionEvent*)&ev; - - if (pev->x < xmin || pev->x > xmax || - pev->y < ymin || pev->y > ymax) - { - if (button->state == - MBWMDecorButtonStatePressed) - { - button->state = - MBWMDecorButtonStateInactive; - mb_wm_theme_paint_button (wm->theme,button); - } - } - else - { - if (button->state != - MBWMDecorButtonStatePressed) - { - button->state = MBWMDecorButtonStatePressed; - mb_wm_theme_paint_button (wm->theme,button); - } - } - } - break; - case EnterNotify: - if (button->state == MBWMDecorButtonStateInactive) - { - button->state = MBWMDecorButtonStatePressed; - mb_wm_theme_paint_button (wm->theme, button); - } - break; - case LeaveNotify: - if (button->state != MBWMDecorButtonStateInactive) - { - button->state = MBWMDecorButtonStateInactive; - mb_wm_theme_paint_button (wm->theme, button); - } - break; - case ButtonRelease: - { - XButtonEvent *pev = (XButtonEvent*)&ev; - - if (button->state != MBWMDecorButtonStateInactive) - { - button->state = MBWMDecorButtonStateInactive; - mb_wm_theme_paint_button (wm->theme, button); - } - - XUngrabPointer (wm->xdpy, CurrentTime); - XSync (wm->xdpy, False); /* necessary */ - - if (pev->x < xmin || pev->x > xmax || - pev->y < ymin || pev->y > ymax) - { - retval = False; - goto done; - } - - if (button->release) - button->release(wm, button, button->userdata); - else - mb_wm_decor_button_stock_button_action (button); - - return False; - } - } - } - else - { - /* - * No pending X event, so spin the main loop (this allows - * things like timers to work. - */ - mb_wm_main_context_spin_loop (wm->main_ctx); - } - } - } - } + /* + * First, call the custom function if any. + */ + if (button->press) + button->press(wm, button, button->userdata); - retval = False; + if (XGrabPointer(wm->xdpy, xev->subwindow, False, + ButtonPressMask|ButtonReleaseMask| + PointerMotionMask|EnterWindowMask|LeaveWindowMask, + GrabModeAsync, + GrabModeAsync, + None, None, CurrentTime) == GrabSuccess) + { + decor->motion_cb_id = mb_wm_manager_add_event_handler ( + wm, + decor->xwin, + MotionNotify, + (MBWMXEventFunc)button_grab_handler, + button); + decor->enter_cb_id = mb_wm_manager_add_event_handler ( + wm, + decor->xwin, + EnterNotify, + (MBWMXEventFunc)button_grab_handler, + button); + decor->leave_cb_id = mb_wm_manager_add_event_handler ( + wm, + decor->xwin, + LeaveNotify, + (MBWMXEventFunc)button_grab_handler, + button); + decor->release_cb_id = mb_wm_manager_add_event_handler ( + wm, + decor->xwin, + ButtonRelease, + (MBWMXEventFunc)button_grab_handler, + button); + + if (button->state == MBWMDecorButtonStateInactive) + { + button->state = MBWMDecorButtonStatePressed; + mb_wm_theme_paint_button (wm->theme, button); + } + } } - done: - g_list_free (l); - return retval; + return True; } static void @@ -1052,7 +1060,7 @@ static void mb_wm_decor_button_destroy (MBWMObject* obj) { MBWMDecorButton * button = MB_WM_DECOR_BUTTON (obj); - MBWMMainContext * ctx = button->decor->parent_client->wmref->main_ctx; + MBWMManager * wm = button->decor->parent_client->wmref; if (button->userdata && button->destroy_userdata) { @@ -1068,8 +1076,7 @@ mb_wm_decor_button_destroy (MBWMObject* obj) button->destroy_themedata = NULL; } - mb_wm_main_context_x_event_handler_remove (ctx, ButtonPress, - button->press_cb_id); + mb_wm_manager_remove_event_handler (wm, ButtonPress, button->press_cb_id); } static void @@ -1079,7 +1086,7 @@ mb_wm_decor_button_realize (MBWMDecorButton *button) MBWMManager *wm = decor->parent_client->wmref; button->press_cb_id = - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, decor->xwin, ButtonPress, (MBWMXEventFunc)mb_wm_decor_button_press_handler, diff --git a/matchbox/mb-wm-decor.h b/matchbox/mb-wm-decor.h index a25ffdb..b8b3d10 100644 --- a/matchbox/mb-wm-decor.h +++ b/matchbox/mb-wm-decor.h @@ -73,6 +73,9 @@ struct MBWMDecor unsigned long press_cb_id; unsigned long release_cb_id; + unsigned long motion_cb_id; + unsigned long enter_cb_id; + unsigned long leave_cb_id; void *themedata; MBWMDecorDestroyUserData destroy_themedata; diff --git a/matchbox/mb-wm-main-context.c b/matchbox/mb-wm-main-context.c deleted file mode 100644 index d9e7819..0000000 --- a/matchbox/mb-wm-main-context.c +++ /dev/null @@ -1,1116 +0,0 @@ -#include "mb-wm-main-context.h" - -#include <sys/time.h> -#include <poll.h> -#include <limits.h> -#include <fcntl.h> - -#if ENABLE_COMPOSITE -#include <X11/extensions/Xdamage.h> -#endif - -#define MBWM_CTX_MAX_TIMEOUT 100 - -#if MBWM_WANT_DEBUG - -static const char *MBWMDEBUGEvents[] = { - "error", - "reply", - "KeyPress", - "KeyRelease", - "ButtonPress", - "ButtonRelease", - "MotionNotify", - "EnterNotify", - "LeaveNotify", - "FocusIn", - "FocusOut", - "KeymapNotify", - "Expose", - "GraphicsExpose", - "NoExpose", - "VisibilityNotify", - "CreateNotify", - "DestroyNotify", - "UnmapNotify", - "MapNotify", - "MapRequest", - "ReparentNotify", - "ConfigureNotify", - "ConfigureRequest", - "GravityNotify", - "ResizeRequest", - "CirculateNotify", - "CirculateRequest", - "PropertyNotify", - "SelectionClear", - "SelectionRequest", - "SelectionNotify", - "ColormapNotify", - "ClientMessage", - "MappingNotify", -}; - -#endif - -static Bool -mb_wm_main_context_check_timeouts (MBWMMainContext *ctx); - -static Bool -mb_wm_main_context_check_fd_watches (MBWMMainContext * ctx); - -static Bool -mb_wm_main_context_spin_xevent (MBWMMainContext *ctx); - -struct MBWMTimeOutEventInfo -{ - int ms; - MBWMManagerTimeOutFunc func; - void *userdata; - unsigned long id; - struct timeval triggers; - -}; - -struct MBWMFdWatchInfo{ - MBWMIOChannel *channel; - MBWMIOCondition events; - MBWMManagerFdWatchFunc func; - void *userdata; - unsigned long id; -}; - -static void -mb_wm_main_context_class_init (MBWMObjectClass *klass) -{ -#if MBWM_WANT_DEBUG - klass->klass_name = "MBWMMainContext"; -#endif -} - -static void -mb_wm_main_context_destroy (MBWMObject *this) -{ -} - -#if USE_GLIB_MAINLOOP -gboolean -mb_wm_main_context_gloop_xevent (gpointer userdata) -{ - MBWMMainContext * ctx = userdata; - MBWMManager * wm = ctx->wm; - - while (mb_wm_main_context_spin_xevent (ctx)); - - if (wm->sync_type) - mb_wm_manager_sync (wm); - - return TRUE; -} -#endif - -static int -mb_wm_main_context_init (MBWMObject *this, va_list vap) -{ - MBWMMainContext *ctx = MB_WM_MAIN_CONTEXT (this); - MBWMManager *wm = NULL; - MBWMObjectProp prop; - - prop = va_arg(vap, MBWMObjectProp); - while (prop) - { - if (prop == MBWMObjectPropWm) - { - wm = va_arg(vap, MBWMManager *); - break; - } - else - MBWMO_PROP_EAT (vap, prop); - - prop = va_arg (vap, MBWMObjectProp); - } - - ctx->wm = wm; - - return 1; -} - -int -mb_wm_main_context_class_type () -{ - static int type = 0; - - if (UNLIKELY(type == 0)) - { - static MBWMObjectClassInfo info = { - sizeof (MBWMMainContextClass), - sizeof (MBWMMainContext), - mb_wm_main_context_init, - mb_wm_main_context_destroy, - mb_wm_main_context_class_init - }; - type = mb_wm_object_register_class (&info, MB_WM_TYPE_OBJECT, 0); - } - - return type; -} - -MBWMMainContext* -mb_wm_main_context_new (MBWMManager *wm) -{ - MBWMMainContext *ctx; - - ctx = MB_WM_MAIN_CONTEXT (mb_wm_object_new (MB_WM_TYPE_MAIN_CONTEXT, - MBWMObjectPropWm, wm, - NULL)); - - return ctx; -} - -Bool -mb_wm_main_context_handle_x_event (XEvent *xev, - MBWMMainContext *ctx) -{ - MBWMManager *wm = ctx->wm; - GList *iter; - Window xwin = xev->xany.window; - -#if (MBWM_WANT_DEBUG) - { - if (mbwm_debug_flags & MBWM_DEBUG_EVENT) - { - MBWindowManagerClient *ev_client; - - ev_client = mb_wm_manager_managed_window_from_xwindow(wm, xev->xany.window); - - printf (" @ XEvent: '%s:%i' for %lx %s%s\n", - xev->type < sizeof (MBWMDEBUGEvents)/sizeof(MBWMDEBUGEvents[0]) - ? MBWMDEBUGEvents[xev->type] : "unknown", - xev->type, - xev->xany.window, - xev->xany.window == wm->root_win->xwindow ? "(root)" : "", - ev_client ? ev_client->name : "" - ); - } - } -#endif - -#define XE_ITER_GET_FUNC(i) (((MBWMXEventFuncInfo *)((i)->data))->func) -#define XE_ITER_GET_DATA(i) ((MBWMXEventFuncInfo *)((i)->data))->userdata -#define XE_ITER_GET_XWIN(i) ((MBWMXEventFuncInfo *)((i)->data))->xwindow - -#if ENABLE_COMPOSITE - if (xev->type == wm->damage_event_base + XDamageNotify) - { - iter = ctx->event_funcs.damage_notify; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMXEventFunc)XE_ITER_GET_FUNC(iter) - (xev, XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - } - else -#endif - switch (xev->type) - { - case ClientMessage: - /* - * TODO -- perhaps this should not be special-cased. - */ - if (xev->xany.window == wm->root_win->xwindow || - ((XClientMessageEvent *)xev)->message_type == - wm->atoms[MBWM_ATOM_NET_ACTIVE_WINDOW] || - ((XClientMessageEvent *)xev)->message_type == - wm->atoms[MBWM_ATOM_NET_WM_STATE]) - { - mb_wm_root_window_handle_message (wm->root_win, - (XClientMessageEvent *)xev); - } - - iter = ctx->event_funcs.client_message; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWindowManagerClientMessageFunc)XE_ITER_GET_FUNC(iter) - ((XClientMessageEvent*)&xev->xclient, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case Expose: - break; - case MapRequest: - iter = ctx->event_funcs.map_request; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerMapRequestFunc)XE_ITER_GET_FUNC(iter) - ((XMapRequestEvent*)&xev->xmaprequest, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case MapNotify: - iter = ctx->event_funcs.map_notify; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerMapNotifyFunc)XE_ITER_GET_FUNC(iter) - ((XMapEvent*)&xev->xmap, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case UnmapNotify: -#if MBWM_WANT_DEBUG - if (mbwm_debug_flags & MBWM_DEBUG_EVENT) - { - XUnmapEvent * uev = & xev->xunmap; - printf (" window %x, event %x, %d\n", - uev->window, - uev->event, - uev->from_configure); - } -#endif - xwin = xev->xunmap.window; - iter = ctx->event_funcs.unmap_notify; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerUnmapNotifyFunc)XE_ITER_GET_FUNC(iter) - ((XUnmapEvent*)&xev->xunmap, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case DestroyNotify: - iter = ctx->event_funcs.destroy_notify; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerDestroyNotifyFunc)XE_ITER_GET_FUNC(iter) - ((XDestroyWindowEvent*)&xev->xdestroywindow, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case ConfigureNotify: -#if MBWM_WANT_DEBUG - if (mbwm_debug_flags & MBWM_DEBUG_EVENT) - { - XConfigureEvent * cev = & xev->xconfigure; - printf (" window %x, event %x, [%d,%d;%dx%d]\n", - cev->window, - cev->event, - cev->x, - cev->y, - cev->width, - cev->height); - } -#endif - xwin = xev->xconfigure.window; - iter = ctx->event_funcs.configure_notify; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerConfigureNotifyFunc)XE_ITER_GET_FUNC(iter) - ((XConfigureEvent*)&xev->xconfigure, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case ConfigureRequest: -#if MBWM_WANT_DEBUG - if (mbwm_debug_flags & MBWM_DEBUG_EVENT) - { - XConfigureRequestEvent * cev = & xev->xconfigurerequest; - printf (" window %x, parent %x, [%d,%d;%dx%d]\n", - cev->window, - cev->parent, - cev->x, - cev->y, - cev->width, - cev->height); - } -#endif - xwin = xev->xconfigurerequest.window; - iter = ctx->event_funcs.configure_request; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerConfigureRequestFunc)XE_ITER_GET_FUNC(iter) - ((XConfigureRequestEvent*)&xev->xconfigurerequest, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case KeyPress: - iter = ctx->event_funcs.key_press; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerKeyPressFunc)XE_ITER_GET_FUNC(iter) - ((XKeyEvent*)&xev->xkey, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case PropertyNotify: -#if MBWM_WANT_DEBUG - if (mbwm_debug_flags & MBWM_DEBUG_EVENT) - { - XPropertyEvent * pev = & xev->xproperty; - char * prop = XGetAtomName (wm->xdpy, pev->atom); - printf (" window %x, prop %s, state %d\n", - pev->window, - prop, - pev->state); - - if (prop) - XFree (prop); - } -#endif - xwin = xev->xproperty.window; - iter = ctx->event_funcs.property_notify; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerPropertyNotifyFunc)XE_ITER_GET_FUNC(iter) - ((XPropertyEvent*)&xev->xproperty, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case ButtonPress: - iter = ctx->event_funcs.button_press; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerButtonPressFunc)XE_ITER_GET_FUNC(iter) - ((XButtonEvent*)&xev->xbutton, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case ButtonRelease: - iter = ctx->event_funcs.button_release; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerButtonReleaseFunc)XE_ITER_GET_FUNC(iter) - ((XButtonEvent*)&xev->xbutton, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - case MotionNotify: - iter = ctx->event_funcs.motion_notify; - - while (iter) - { - Window msg_xwin = XE_ITER_GET_XWIN(iter); - GList * next = iter->next; - - if (msg_xwin == None || msg_xwin == xwin) - { - if (!(MBWMManagerMotionNotifyFunc)XE_ITER_GET_FUNC(iter) - ((XMotionEvent*)&xev->xmotion, - XE_ITER_GET_DATA(iter))) - break; - } - - iter = next; - } - break; - } - - return False; -} - -static Bool -mb_wm_main_context_spin_xevent (MBWMMainContext *ctx) -{ - MBWMManager * wm = ctx->wm; - XEvent xev; - - if (!XEventsQueued (wm->xdpy, QueuedAfterFlush)) - return False; - - XNextEvent(wm->xdpy, &xev); - - mb_wm_main_context_handle_x_event (&xev, ctx); - - return (XEventsQueued (wm->xdpy, QueuedAfterReading) != 0); -} - -static Bool -mb_wm_main_context_spin_xevent_blocking (MBWMMainContext *ctx) -{ - MBWMManager * wm = ctx->wm; - XEvent xev; - - XNextEvent(wm->xdpy, &xev); - - mb_wm_main_context_handle_x_event (&xev, ctx); - - return (XEventsQueued (wm->xdpy, QueuedAfterReading) != 0); -} - -void -mb_wm_main_context_loop (MBWMMainContext *ctx) -{ -#if ! USE_GLIB_MAINLOOP - MBWMManager * wm = ctx->wm; - - while (True) - { - Bool sources; - - sources = mb_wm_main_context_check_timeouts (ctx); - sources |= mb_wm_main_context_check_fd_watches (ctx); - - if (!sources) - { - /* No timeouts, idles, etc. -- wait for next - * X event - */ - mb_wm_main_context_spin_xevent_blocking (ctx); - } - else - { - /* Process any pending xevents */ - while (mb_wm_main_context_spin_xevent (ctx)); - } - - if (wm->sync_type) - mb_wm_manager_sync (wm); - } -#endif -} - -Bool -mb_wm_main_context_spin_loop (MBWMMainContext *ctx) -{ -#if USE_GLIB_MAINLOOP - g_main_context_iteration (NULL, FALSE); - return g_main_context_pending (NULL); -#else - return mb_wm_main_context_spin_xevent (ctx); -#endif -} - - -unsigned long -mb_wm_main_context_x_event_handler_add (MBWMMainContext *ctx, - Window xwin, - int type, - MBWMXEventFunc func, - void *userdata) -{ - static unsigned long ids = 0; - MBWMXEventFuncInfo * func_info; -#if ENABLE_COMPOSITE - MBWMManager * wm = ctx->wm; -#endif - - ++ids; - - func_info = mb_wm_util_malloc0(sizeof(MBWMXEventFuncInfo)); - func_info->func = func; - func_info->xwindow = xwin; - func_info->userdata = userdata; - func_info->id = ids; - -#if ENABLE_COMPOSITE - if (type == wm->damage_event_base + XDamageNotify) - { - ctx->event_funcs.damage_notify = - g_list_append (ctx->event_funcs.damage_notify, func_info); - } - else -#endif - switch (type) - { - case Expose: - break; - case MapRequest: - ctx->event_funcs.map_request = - g_list_append (ctx->event_funcs.map_request, func_info); - break; - case MapNotify: - ctx->event_funcs.map_notify= - g_list_append (ctx->event_funcs.map_notify, func_info); - break; - case UnmapNotify: - ctx->event_funcs.unmap_notify= - g_list_append (ctx->event_funcs.unmap_notify, func_info); - break; - case DestroyNotify: - ctx->event_funcs.destroy_notify = - g_list_append (ctx->event_funcs.destroy_notify, func_info); - break; - case ConfigureNotify: - ctx->event_funcs.configure_notify = - g_list_append (ctx->event_funcs.configure_notify, func_info); - break; - case ConfigureRequest: - ctx->event_funcs.configure_request = - g_list_append (ctx->event_funcs.configure_request, func_info); - break; - case KeyPress: - ctx->event_funcs.key_press = - g_list_append (ctx->event_funcs.key_press, func_info); - break; - case PropertyNotify: - ctx->event_funcs.property_notify = - g_list_append (ctx->event_funcs.property_notify, func_info); - break; - case ButtonPress: - ctx->event_funcs.button_press = - g_list_append (ctx->event_funcs.button_press, func_info); - break; - case ButtonRelease: - ctx->event_funcs.button_release = - g_list_append (ctx->event_funcs.button_release, func_info); - break; - case MotionNotify: - ctx->event_funcs.motion_notify = - g_list_append (ctx->event_funcs.motion_notify, func_info); - break; - case ClientMessage: - ctx->event_funcs.client_message = - g_list_append (ctx->event_funcs.client_message, func_info); - break; - - default: - break; - } - - return ids; -} - -void -mb_wm_main_context_x_event_handler_remove (MBWMMainContext *ctx, - int type, - unsigned long id) -{ - GList * l = NULL; - GList **l_start; - -#if ENABLE_COMPOSITE - MBWMManager * wm = ctx->wm; - - if (type == wm->damage_event_base + XDamageNotify) - { - l_start = &ctx->event_funcs.damage_notify; - } - else -#endif - switch (type) - { - case Expose: - break; - case MapRequest: - l_start = &ctx->event_funcs.map_request; - break; - case MapNotify: - l_start = &ctx->event_funcs.map_notify; - break; - case UnmapNotify: - l_start = &ctx->event_funcs.unmap_notify; - break; - case DestroyNotify: - l_start = &ctx->event_funcs.destroy_notify; - break; - case ConfigureNotify: - l_start = &ctx->event_funcs.configure_notify; - break; - case ConfigureRequest: - l_start = &ctx->event_funcs.configure_request; - break; - case KeyPress: - l_start = &ctx->event_funcs.key_press; - break; - case PropertyNotify: - l_start = &ctx->event_funcs.property_notify; - break; - case ButtonPress: - l_start = &ctx->event_funcs.button_press; - break; - case ButtonRelease: - l_start = &ctx->event_funcs.button_release; - break; - case MotionNotify: - l_start = &ctx->event_funcs.motion_notify; - break; - case ClientMessage: - l_start = &ctx->event_funcs.client_message; - break; - - default: - break; - } - - l = *l_start; - - while (l) - { - MBWMXEventFuncInfo * info = l->data; - - if (info->id == id) - { - GList * prev = l->prev; - GList * next = l->next; - - if (prev) - prev->next = next; - else - *l_start = next; - - if (next) - next->prev = prev; - - free (info); - free (l); - - return; - } - - l = l->next; - } -} - -#if ! USE_GLIB_MAINLOOP -static void -mb_wm_main_context_timeout_setup (MBWMTimeOutEventInfo * tinfo, - struct timeval * current_time) -{ - int sec = tinfo->ms / 1000; - int usec = (tinfo->ms - sec *1000) * 1000; - - sec += current_time->tv_sec; - usec += current_time->tv_usec; - - if (usec >= 1000000) - { - usec -= 1000000; - sec++; - } - - tinfo->triggers.tv_sec = sec; - tinfo->triggers.tv_usec = usec; -} - -static Bool -mb_wm_main_context_handle_timeout (MBWMTimeOutEventInfo *tinfo, - struct timeval *current_time) -{ - if (tinfo->triggers.tv_sec < current_time->tv_sec || - (tinfo->triggers.tv_sec == current_time->tv_sec && - tinfo->triggers.tv_usec <= current_time->tv_usec)) - { - if (!tinfo->func (tinfo->userdata)) - return False; - - mb_wm_main_context_timeout_setup (tinfo, current_time); - } - - return True; -} - -/* - * Returns false if no timeouts are present - */ -static Bool -mb_wm_main_context_check_timeouts (MBWMMainContext *ctx) -{ - GList * l = g_list_first(ctx->event_funcs.timeout); - struct timeval current_time; - - if (!l) - return False; - - gettimeofday (¤t_time, NULL); - - while (l) - { - MBWMTimeOutEventInfo * tinfo = l->data; - unsigned long tid = tinfo->id; - - if (!mb_wm_main_context_handle_timeout (tinfo, ¤t_time)) - { - /* Timeout handler notified it can be removed, do so now */ - mb_wm_main_context_timeout_handler_remove (ctx,tid); - /* To avoid race condition, restart at front of list */ - l = g_list_first(ctx->event_funcs.timeout); - } - else - l = g_list_next(l); - } - return True; -} -#endif /* !USE_GLIB_MAINLOOP */ - -unsigned long -mb_wm_main_context_timeout_handler_add (MBWMMainContext *ctx, - int ms, - MBWMManagerTimeOutFunc func, - void *userdata) -{ -#if ! USE_GLIB_MAINLOOP - static unsigned long ids = 0; - MBWMTimeOutEventInfo * tinfo; - struct timeval current_time; - - ++ids; - - tinfo = mb_wm_util_malloc0 (sizeof (MBWMTimeOutEventInfo)); - tinfo->func = func; - tinfo->id = ids; - tinfo->ms = ms; - tinfo->userdata = userdata; - - gettimeofday (¤t_time, NULL); - mb_wm_main_context_timeout_setup (tinfo, ¤t_time); - - ctx->event_funcs.timeout = - g_list_append (ctx->event_funcs.timeout, tinfo); - - return ids; - -#else - return g_timeout_add (ms, func, userdata); -#endif -} - -void -mb_wm_main_context_timeout_handler_remove (MBWMMainContext *ctx, - unsigned long id) -{ -#if ! USE_GLIB_MAINLOOP - GList * l = ctx->event_funcs.timeout; - - while (l) - { - MBWMTimeOutEventInfo * info = l->data; - - if (info->id == id) - { - /* Reset list head after entry removal */ - ctx->event_funcs.timeout = - g_list_remove(ctx->event_funcs.timeout, l->data); - return; - } - - l = g_list_next(l); - } -#else - g_source_remove (id); -#endif -} - -unsigned long -mb_wm_main_context_fd_watch_add (MBWMMainContext *ctx, - MBWMIOChannel *channel, - MBWMIOCondition events, - MBWMManagerFdWatchFunc func, - void *userdata) -{ -#if ! USE_GLIB_MAINLOOP - static unsigned long ids = 0; - MBWMFdWatchInfo * finfo; - struct pollfd * fds; - - ++ids; - - finfo = mb_wm_util_malloc0 (sizeof (MBWMFdWatchInfo)); - finfo->func = func; - finfo->id = ids; - finfo->channel = channel; - finfo->events = events; - finfo->userdata = userdata; - - ctx->event_funcs.fd_watch = - g_list_append (ctx->event_funcs.fd_watch, finfo); - - ctx->n_poll_fds++; - ctx->poll_fds = realloc (ctx->poll_fds, sizeof (struct pollfd)); - - fds = ctx->poll_fds + (ctx->n_poll_fds - 1); - fds->fd = *channel; - fds->events = events; - - return ids; - -#else - return g_io_add_watch (channel, events, func, userdata); -#endif -} - -void -mb_wm_main_context_fd_watch_remove (MBWMMainContext *ctx, - unsigned long id) -{ -#if ! USE_GLIB_MAINLOOP - GList * l = ctx->event_funcs.fd_watch; - - while (l) - { - MBWMFdWatchInfo * info = l->data; - - if (info->id == id) - { - GList * prev = l->prev; - GList * next = l->next; - - if (prev) - prev->next = next; - else - ctx->event_funcs.fd_watch = next; - - if (next) - next->prev = prev; - - free (info); - free (l); - - return; - } - - l = l->next; - } - - ctx->n_poll_fds--; - ctx->poll_cache_dirty = True; -#else - g_source_remove (id); -#endif -} - -MBWMIOChannel * -mb_wm_main_context_io_channel_new (int fd) -{ -#if ! USE_GLIB_MAINLOOP - MBWMIOChannel * c = mb_wm_util_malloc0 (sizeof (MBWMIOChannel)); - *c = fd; - return c; -#else - return g_io_channel_unix_new (fd); -#endif -} - - -void -mb_wm_main_context_io_channel_destroy (MBWMIOChannel * channel) -{ -#if ! USE_GLIB_MAINLOOP - if (channel) - free (channel); -#else - g_io_channel_unref (channel); -#endif -} - -int -mb_wm_main_context_io_channel_get_fd (MBWMIOChannel * channel) -{ -#if ! USE_GLIB_MAINLOOP - return *channel; -#else - g_io_channel_unix_get_fd (channel); -#endif -} - -#if ! USE_GLIB_MAINLOOP -static void -mb_wm_main_context_setup_poll_cache (MBWMMainContext *ctx) -{ - GList *l = ctx->event_funcs.fd_watch; - int i = 0; - - if (!ctx->poll_cache_dirty) - return; - - ctx->poll_fds = realloc (ctx->poll_fds, ctx->n_poll_fds); - - while (l) - { - MBWMFdWatchInfo *info = l->data; - - ctx->poll_fds[i].fd = *(info->channel); - ctx->poll_fds[i].events = info->events; - - l = l->next; - ++i; - } - - ctx->poll_cache_dirty = False; -} - -static Bool -mb_wm_main_context_check_fd_watches (MBWMMainContext * ctx) -{ - int ret; - int i = 0; - GList * l = ctx->event_funcs.fd_watch; - Bool removal = False; - - if (!ctx->n_poll_fds) - return False; - - mb_wm_main_context_setup_poll_cache (ctx); - - ret = poll (ctx->poll_fds, ctx->n_poll_fds, 0); - - if (ret < 0) - { - MBWM_DBG ("Poll failed."); - return True; - } - - if (ret == 0) - return True; - - while (l) - { - MBWMFdWatchInfo *info = l->data; - - if (ctx->poll_fds[i].revents & ctx->poll_fds[i].events) - { - Bool zap = !info->func (info->channel, ctx->poll_fds[i].revents, - info->userdata); - - if (zap) - { - GList * prev = l->prev; - GList * next = l->next; - - if (prev) - prev->next = next; - else - ctx->event_funcs.fd_watch = next; - - if (next) - next->prev = prev; - - free (info); - free (l); - - ctx->n_poll_fds--; - - removal = True; - - l = next; - } - else - l = l->next; - } - else - l = l->next; - - ++i; - } - - ctx->poll_cache_dirty = removal; - - return True; -} -#endif diff --git a/matchbox/mb-wm-main-context.h b/matchbox/mb-wm-main-context.h deleted file mode 100644 index 6a84cc2..0000000 --- a/matchbox/mb-wm-main-context.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Matchbox Window Manager II - A lightweight window manager not for the - * desktop. - * - * Authored By Matthew Allum <mallum@o-hand.com> - * - * Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _HAVE_MB_MAIN_CONTEXT_H -#define _HAVE_MB_MAIN_CONTEXT_H - -#include <matchbox/mb-wm-object.h> -#include <matchbox/mb-wm-manager.h> -#include <poll.h> - -#define MB_WM_MAIN_CONTEXT(c) ((MBWMMainContext*)(c)) -#define MB_WM_MAIN_CONTEXT_CLASS(c) ((MBWMMainContextClass*)(c)) -#define MB_WM_TYPE_MAIN_CONTEXT (mb_wm_main_context_class_type ()) -#define MB_WM_IS_MAIN_CONTEXT(c) (MB_WM_OBJECT_TYPE(c)==MB_WM_TYPE_MAIN_CONTEXT) - -/* XXX: we have a circular dependency between mb-wm-main-context.h - * and mb-window-manager.h */ -#ifndef MB_WM_MAIN_CONTEXT_TYPEDEF_DEFINED -typedef struct MBWMMainContext MBWMMainContext; -#define MB_WM_MAIN_CONTEXT_TYPEDEF_DEFINED -#endif -typedef struct MBWMMainContextClass MBWMMainContextClass; - -typedef Bool (*MBWMMainContextXEventFunc) (XEvent * xev, void * userdata); - -typedef struct MBWMEventFuncs -{ - /* FIXME: figure our X wrap / unwrap mechanism */ - GList *map_notify; - GList *unmap_notify; - GList *map_request; - GList *destroy_notify; - GList *configure_request; - GList *configure_notify; - GList *key_press; - GList *property_notify; - GList *button_press; - GList *button_release; - GList *motion_notify; - GList *client_message; - -#if ENABLE_COMPOSITE - GList *damage_notify; -#endif - -#if ! USE_GLIB_MAINLOOP - GList *timeout; - GList *fd_watch; -#endif -} -MBWMEventFuncs; - -struct MBWMMainContext -{ - MBWMObject parent; - - MBWMManager *wm; - - MBWMEventFuncs event_funcs; - struct pollfd *poll_fds; - int n_poll_fds; - Bool poll_cache_dirty; -}; - -struct MBWMMainContextClass -{ - MBWMObjectClass parent; -}; - -int -mb_wm_main_context_class_type (); - -MBWMMainContext* -mb_wm_main_context_new(MBWMManager *wm); - -unsigned long -mb_wm_main_context_x_event_handler_add (MBWMMainContext *ctx, - Window xwin, - int type, - MBWMXEventFunc func, - void *userdata); - -void -mb_wm_main_context_x_event_handler_remove (MBWMMainContext *ctx, - int type, - unsigned long id); - -unsigned long -mb_wm_main_context_timeout_handler_add (MBWMMainContext *ctx, - int ms, - MBWMManagerTimeOutFunc func, - void *userdata); - -void -mb_wm_main_context_timeout_handler_remove (MBWMMainContext *ctx, - unsigned long id); - -MBWMIOChannel * -mb_wm_main_context_io_channel_new (int fd); - -void -mb_wm_main_context_io_channel_destroy (MBWMIOChannel * channel); - -int -mb_wm_main_context_io_channel_get_fd (MBWMIOChannel * channel); - -unsigned long -mb_wm_main_context_fd_watch_add (MBWMMainContext *ctx, - MBWMIOChannel *channel, - MBWMIOCondition events, - MBWMManagerFdWatchFunc func, - void *userdata); - -void -mb_wm_main_context_fd_watch_remove (MBWMMainContext *ctx, - unsigned long id); - -#if USE_GLIB_MAINLOOP -gboolean -mb_wm_main_context_gloop_xevent (gpointer userdata); -#endif - -Bool -mb_wm_main_context_handle_x_event (XEvent *xev, - MBWMMainContext *ctx); - -void -mb_wm_main_context_loop (MBWMMainContext *ctx); - -Bool -mb_wm_main_context_spin_loop (MBWMMainContext *ctx); - -#endif diff --git a/matchbox/mb-wm-manager.c b/matchbox/mb-wm-manager.c index 1d87e85..1a110ab 100644 --- a/matchbox/mb-wm-manager.c +++ b/matchbox/mb-wm-manager.c @@ -36,15 +36,6 @@ # include <X11/extensions/Xcomposite.h> #endif -/* FIXME: libmatchbox shouldn't know anything about clutter */ -#ifdef MANAGER_CLUTTER -#include <clutter/x11/clutter-x11.h> -#endif - -#if USE_GTK -# include <gdk/gdk.h> -#endif - #include <stdarg.h> #include <X11/Xmd.h> @@ -59,6 +50,80 @@ #include <X11/cursorfont.h> +#if MBWM_WANT_DEBUG + +static const char *MBWMDEBUGEvents[] = { + "error", + "reply", + "KeyPress", + "KeyRelease", + "ButtonPress", + "ButtonRelease", + "MotionNotify", + "EnterNotify", + "LeaveNotify", + "FocusIn", + "FocusOut", + "KeymapNotify", + "Expose", + "GraphicsExpose", + "NoExpose", + "VisibilityNotify", + "CreateNotify", + "DestroyNotify", + "UnmapNotify", + "MapNotify", + "MapRequest", + "ReparentNotify", + "ConfigureNotify", + "ConfigureRequest", + "GravityNotify", + "ResizeRequest", + "CirculateNotify", + "CirculateRequest", + "PropertyNotify", + "SelectionClear", + "SelectionRequest", + "SelectionNotify", + "ColormapNotify", + "ClientMessage", + "MappingNotify", +}; + +#endif + +typedef struct _MBWMManagerEventSource +{ + MBWMManager *wm; + GSource source; + GPollFD event_poll_fd; +} MBWMManagerEventSource; + +static gboolean +mb_wm_manager_event_prepare (GSource *source, + int *timeout); + +static gboolean +mb_wm_manager_event_check (GSource *source); + +static gboolean +mb_wm_manager_event_dispatch (GSource *source, + GSourceFunc callback, + void *user_data); + +static GSourceFuncs event_funcs = { + mb_wm_manager_event_prepare, + mb_wm_manager_event_check, + mb_wm_manager_event_dispatch, + NULL +}; + +typedef struct _MBWMXlibFilterClosure +{ + MBWMXlibFilterFunc filter; + void *data; +} MBWMXlibFilterClosure; + static void mb_wm_process_cmdline (MBWMManager *wm); @@ -166,76 +231,6 @@ mb_wm_layout_new_real (MBWMManager *wm) return layout; } -#if USE_GTK -static GdkFilterReturn -mb_wm_gdk_xevent_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) -{ - MBWMManager * wm = data; - XEvent * xev = (XEvent*) xevent; - - mb_wm_main_context_handle_x_event (xev, wm->main_ctx); - - if (wm->sync_type) - mb_wm_manager_sync (wm); - - return GDK_FILTER_CONTINUE; -} -#endif - -/* FIXME: libmatchbox shouldn't know anything about clutter! */ -#ifdef MANAGER_CLUTTER -#if USE_GTK -static GdkFilterReturn -mb_wm_clutter_gdk_xevent_filter (GdkXEvent *xevent, GdkEvent *event, - gpointer data) -{ - switch (clutter_x11_handle_event ((XEvent*)xevent)) - { - default: - case CLUTTER_X11_FILTER_CONTINUE: - return GDK_FILTER_CONTINUE; - case CLUTTER_X11_FILTER_TRANSLATE: - return GDK_FILTER_TRANSLATE; - case CLUTTER_X11_FILTER_REMOVE: - return GDK_FILTER_REMOVE; - } - - return GDK_FILTER_CONTINUE; -} -#else -static ClutterX11FilterReturn -mb_wm_clutter_xevent_filter (XEvent *xev, ClutterEvent *cev, gpointer data) -{ - MBWMManager * wm = data; - - mb_wm_main_context_handle_x_event (xev, wm->main_ctx); - - if (wm->sync_type) - mb_wm_manager_sync (wm); - - return CLUTTER_X11_FILTER_CONTINUE; -} -#endif -#endif - -#if MANAGER_CLUTTER || USE_GTK -static void -mb_wm_main_real (MBWMManager *wm) -{ - -#if USE_GTK - gdk_window_add_filter (NULL, mb_wm_gdk_xevent_filter, wm); -#if MANAGER_CLUTTER - gdk_window_add_filter (NULL, mb_wm_clutter_gdk_xevent_filter, NULL); -#endif - gtk_main (); -#else - clutter_x11_add_filter (mb_wm_clutter_xevent_filter, wm); - clutter_main (); -#endif -} -#endif - static void mb_wm_class_init (MBWMObjectClass *klass) { @@ -252,10 +247,6 @@ mb_wm_class_init (MBWMObjectClass *klass) wm_class->layout_new = mb_wm_layout_new_real; wm_class->get_desktop_geometry = mb_wm_real_get_desktop_geometry; -#if MANAGER_CLUTTER - wm_class->main = mb_wm_main_real; -#endif - #if MBWM_WANT_DEBUG klass->klass_name = "MBWMManager"; #endif @@ -280,7 +271,6 @@ mb_wm_destroy (MBWMObject *this) mb_wm_object_unref (MB_WM_OBJECT (wm->root_win)); mb_wm_object_unref (MB_WM_OBJECT (wm->theme)); mb_wm_object_unref (MB_WM_OBJECT (wm->layout)); - mb_wm_object_unref (MB_WM_OBJECT (wm->main_ctx)); } static int @@ -862,15 +852,564 @@ stack_sync_to_display (MBWMManager *wm) mb_wm_util_untrap_x_errors(); } +unsigned long +mb_wm_manager_add_event_handler (MBWMManager *wm, + Window xwin, + int type, + MBWMXEventFunc func, + void *userdata) +{ + static unsigned long ids = 0; + MBWMXEventFuncInfo * func_info; + + ++ids; + + func_info = mb_wm_util_malloc0(sizeof(MBWMXEventFuncInfo)); + func_info->func = func; + func_info->xwindow = xwin; + func_info->userdata = userdata; + func_info->id = ids; + +#if ENABLE_COMPOSITE + if (type == wm->damage_event_base + XDamageNotify) + { + wm->event_funcs.damage_notify = + g_list_append (wm->event_funcs.damage_notify, func_info); + } + else +#endif + switch (type) + { + case Expose: + break; + case MapRequest: + wm->event_funcs.map_request = + g_list_append (wm->event_funcs.map_request, func_info); + break; + case MapNotify: + wm->event_funcs.map_notify= + g_list_append (wm->event_funcs.map_notify, func_info); + break; + case UnmapNotify: + wm->event_funcs.unmap_notify= + g_list_append (wm->event_funcs.unmap_notify, func_info); + break; + case DestroyNotify: + wm->event_funcs.destroy_notify = + g_list_append (wm->event_funcs.destroy_notify, func_info); + break; + case ConfigureNotify: + wm->event_funcs.configure_notify = + g_list_append (wm->event_funcs.configure_notify, func_info); + break; + case ConfigureRequest: + wm->event_funcs.configure_request = + g_list_append (wm->event_funcs.configure_request, func_info); + break; + case KeyPress: + wm->event_funcs.key_press = + g_list_append (wm->event_funcs.key_press, func_info); + break; + case PropertyNotify: + wm->event_funcs.property_notify = + g_list_append (wm->event_funcs.property_notify, func_info); + break; + case ButtonPress: + wm->event_funcs.button_press = + g_list_append (wm->event_funcs.button_press, func_info); + break; + case ButtonRelease: + wm->event_funcs.button_release = + g_list_append (wm->event_funcs.button_release, func_info); + break; + case MotionNotify: + wm->event_funcs.motion_notify = + g_list_append (wm->event_funcs.motion_notify, func_info); + break; + case ClientMessage: + wm->event_funcs.client_message = + g_list_append (wm->event_funcs.client_message, func_info); + break; + + default: + break; + } + + return ids; +} + void -mb_wm_manager_sync (MBWMManager *wm) +mb_wm_manager_remove_event_handler (MBWMManager *wm, + int type, + unsigned long id) +{ + GList * l = NULL; + GList **l_start; + +#if ENABLE_COMPOSITE + if (type == wm->damage_event_base + XDamageNotify) + { + l_start = &wm->event_funcs.damage_notify; + } + else +#endif + switch (type) + { + case Expose: + break; + case MapRequest: + l_start = &wm->event_funcs.map_request; + break; + case MapNotify: + l_start = &wm->event_funcs.map_notify; + break; + case UnmapNotify: + l_start = &wm->event_funcs.unmap_notify; + break; + case DestroyNotify: + l_start = &wm->event_funcs.destroy_notify; + break; + case ConfigureNotify: + l_start = &wm->event_funcs.configure_notify; + break; + case ConfigureRequest: + l_start = &wm->event_funcs.configure_request; + break; + case KeyPress: + l_start = &wm->event_funcs.key_press; + break; + case PropertyNotify: + l_start = &wm->event_funcs.property_notify; + break; + case ButtonPress: + l_start = &wm->event_funcs.button_press; + break; + case ButtonRelease: + l_start = &wm->event_funcs.button_release; + break; + case MotionNotify: + l_start = &wm->event_funcs.motion_notify; + break; + case ClientMessage: + l_start = &wm->event_funcs.client_message; + break; + + default: + break; + } + + l = *l_start; + + while (l) + { + MBWMXEventFuncInfo * info = l->data; + + if (info->id == id) + { + GList * prev = l->prev; + GList * next = l->next; + + if (prev) + prev->next = next; + else + *l_start = next; + + if (next) + next->prev = prev; + + free (info); + free (l); + + return; + } + + l = l->next; + } +} + + + +static void +process_xlib_event (MBWMManager *wm, XEvent *xev) +{ + GList *iter; + Window xwin = xev->xany.window; + +#if (MBWM_WANT_DEBUG) + { + if (mbwm_debug_flags & MBWM_DEBUG_EVENT) + { + MBWindowManagerClient *ev_client; + + ev_client = mb_wm_manager_managed_window_from_xwindow(wm, xev->xany.window); + + printf (" @ XEvent: '%s:%i' for %lx %s%s\n", + xev->type < sizeof (MBWMDEBUGEvents)/sizeof(MBWMDEBUGEvents[0]) + ? MBWMDEBUGEvents[xev->type] : "unknown", + xev->type, + xev->xany.window, + xev->xany.window == wm->root_win->xwindow ? "(root)" : "", + ev_client ? ev_client->name : "" + ); + } + } +#endif + +#define XE_ITER_GET_FUNC(i) (((MBWMXEventFuncInfo *)((i)->data))->func) +#define XE_ITER_GET_DATA(i) ((MBWMXEventFuncInfo *)((i)->data))->userdata +#define XE_ITER_GET_XWIN(i) ((MBWMXEventFuncInfo *)((i)->data))->xwindow + +#if ENABLE_COMPOSITE + if (xev->type == wm->damage_event_base + XDamageNotify) + { + iter = wm->event_funcs.damage_notify; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMXEventFunc)XE_ITER_GET_FUNC(iter) + (xev, XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + } + else +#endif + switch (xev->type) + { + case ClientMessage: + /* + * TODO -- perhaps this should not be special-cased. + */ + if (xev->xany.window == wm->root_win->xwindow || + ((XClientMessageEvent *)xev)->message_type == + wm->atoms[MBWM_ATOM_NET_ACTIVE_WINDOW] || + ((XClientMessageEvent *)xev)->message_type == + wm->atoms[MBWM_ATOM_NET_WM_STATE]) + { + mb_wm_root_window_handle_message (wm->root_win, + (XClientMessageEvent *)xev); + } + + iter = wm->event_funcs.client_message; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWindowManagerClientMessageFunc)XE_ITER_GET_FUNC(iter) + ((XClientMessageEvent*)&xev->xclient, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case Expose: + break; + case MapRequest: + iter = wm->event_funcs.map_request; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerMapRequestFunc)XE_ITER_GET_FUNC(iter) + ((XMapRequestEvent*)&xev->xmaprequest, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case MapNotify: + iter = wm->event_funcs.map_notify; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerMapNotifyFunc)XE_ITER_GET_FUNC(iter) + ((XMapEvent*)&xev->xmap, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case UnmapNotify: +#if MBWM_WANT_DEBUG + if (mbwm_debug_flags & MBWM_DEBUG_EVENT) + { + XUnmapEvent * uev = & xev->xunmap; + printf (" window %x, event %x, %d\n", + uev->window, + uev->event, + uev->from_configure); + } +#endif + xwin = xev->xunmap.window; + iter = wm->event_funcs.unmap_notify; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerUnmapNotifyFunc)XE_ITER_GET_FUNC(iter) + ((XUnmapEvent*)&xev->xunmap, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case DestroyNotify: + iter = wm->event_funcs.destroy_notify; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerDestroyNotifyFunc)XE_ITER_GET_FUNC(iter) + ((XDestroyWindowEvent*)&xev->xdestroywindow, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case ConfigureNotify: +#if MBWM_WANT_DEBUG + if (mbwm_debug_flags & MBWM_DEBUG_EVENT) + { + XConfigureEvent * cev = & xev->xconfigure; + printf (" window %x, event %x, [%d,%d;%dx%d]\n", + cev->window, + cev->event, + cev->x, + cev->y, + cev->width, + cev->height); + } +#endif + xwin = xev->xconfigure.window; + iter = wm->event_funcs.configure_notify; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerConfigureNotifyFunc)XE_ITER_GET_FUNC(iter) + ((XConfigureEvent*)&xev->xconfigure, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case ConfigureRequest: +#if MBWM_WANT_DEBUG + if (mbwm_debug_flags & MBWM_DEBUG_EVENT) + { + XConfigureRequestEvent * cev = & xev->xconfigurerequest; + printf (" window %x, parent %x, [%d,%d;%dx%d]\n", + cev->window, + cev->parent, + cev->x, + cev->y, + cev->width, + cev->height); + } +#endif + xwin = xev->xconfigurerequest.window; + iter = wm->event_funcs.configure_request; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerConfigureRequestFunc)XE_ITER_GET_FUNC(iter) + ((XConfigureRequestEvent*)&xev->xconfigurerequest, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case KeyPress: + iter = wm->event_funcs.key_press; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerKeyPressFunc)XE_ITER_GET_FUNC(iter) + ((XKeyEvent*)&xev->xkey, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case PropertyNotify: +#if MBWM_WANT_DEBUG + if (mbwm_debug_flags & MBWM_DEBUG_EVENT) + { + XPropertyEvent * pev = & xev->xproperty; + char * prop = XGetAtomName (wm->xdpy, pev->atom); + printf (" window %x, prop %s, state %d\n", + pev->window, + prop, + pev->state); + + if (prop) + XFree (prop); + } +#endif + xwin = xev->xproperty.window; + iter = wm->event_funcs.property_notify; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerPropertyNotifyFunc)XE_ITER_GET_FUNC(iter) + ((XPropertyEvent*)&xev->xproperty, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case ButtonPress: + iter = wm->event_funcs.button_press; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerButtonPressFunc)XE_ITER_GET_FUNC(iter) + ((XButtonEvent*)&xev->xbutton, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case ButtonRelease: + iter = wm->event_funcs.button_release; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerButtonReleaseFunc)XE_ITER_GET_FUNC(iter) + ((XButtonEvent*)&xev->xbutton, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + case MotionNotify: + iter = wm->event_funcs.motion_notify; + + while (iter) + { + Window msg_xwin = XE_ITER_GET_XWIN(iter); + GList * next = iter->next; + + if (msg_xwin == None || msg_xwin == xwin) + { + if (!(MBWMManagerMotionNotifyFunc)XE_ITER_GET_FUNC(iter) + ((XMotionEvent*)&xev->xmotion, + XE_ITER_GET_DATA(iter))) + break; + } + + iter = next; + } + break; + } +} + +static void +process_events (MBWMManager *wm) +{ + XEvent *xevent; + + while (xevent = g_queue_pop_tail (wm->event_queue)) + { + process_xlib_event (wm, xevent); + g_slice_free (XEvent, xevent); + } +} + +static void +manager_update (MBWMManager *wm) { /* Sync all changes to display */ MBWindowManagerClient *client = NULL; + process_events (wm); + + if (!wm->sync_type) + return; + MBWM_MARK(); MBWM_TRACE (); + /* XXX: really? why do we do this‽ */ XGrabServer(wm->xdpy); /* First of all, make sure stack is correct */ @@ -1216,46 +1755,35 @@ mb_wm_manager_managed_window_from_frame (MBWMManager *wm, Window frame) return NULL; } -/* - * Run the main loop; there are three options dependent on how we were - * configured at build time: - * - * * If configured without glib main loop integration, we defer to our own - * main loop implementation provided by MBWMMainContext. - * - * * If configured with glib main loop integration: - * - * * If there is an implemetation for the MBWMManager main() virtual - * function, we call it. - * - * * Otherwise, start a normal glib main loop. - */ void -mb_wm_manager_main_loop(MBWMManager *wm) +mb_wm_manager_main_loop (MBWMManager *wm) { -#if !USE_GLIB_MAINLOOP - mb_wm_main_context_loop (wm->main_ctx); -#else - MBWMManagerClass * wm_class = - MB_WM_MANAGER_CLASS (MB_WM_OBJECT_GET_CLASS (wm)); + GMainLoop * loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + g_main_loop_unref (loop); +} -#if !MANAGER_CLUTTER - if (!wm_class->main) - { - GMainLoop * loop = g_main_loop_new (NULL, FALSE); +static gboolean +do_manager_update (MBWMManager *wm) +{ + wm->do_update_idle = 0; - g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - mb_wm_main_context_gloop_xevent, wm->main_ctx, NULL); + manager_update (wm); + return FALSE; +} - g_main_loop_run (loop); - g_main_loop_unref (loop); - } - else -#endif - { - wm_class->main (wm); - } -#endif +void +mb_wm_manager_queue_update (MBWMManager *wm) +{ + /* Note we use a priority slightly higher than the default + * because we need to ensure we consume the events queued + * by a source that has DEFUALT_IDLE priority */ + if (!wm->do_update_idle) + wm->do_update_idle = + g_idle_add_full (G_PRIORITY_HIGH_IDLE, + (GSourceFunc)do_manager_update, + wm, + NULL); } void @@ -1378,7 +1906,7 @@ static void mb_wm_get_desktop_geometry (MBWMManager *wm, MBGeometry * geom) { MBWMManagerClass *wm_class; - + wm_class = (MBWMManagerClass *) MB_WM_OBJECT_GET_CLASS (wm); MBWM_ASSERT (wm_class->get_desktop_geometry); @@ -1497,15 +2025,202 @@ mb_wm_manager_init_comp_extensions (MBWMManager *wm) } #endif +static gboolean +check_xpending (MBWMManager *wm) +{ + return XPending (wm->xdpy); +} + +static gboolean +events_pending (MBWMManager *wm) +{ + return !g_queue_is_empty (wm->event_queue); +} + +static gboolean +mb_wm_manager_event_prepare (GSource *source, + int *timeout) +{ + MBWMManagerEventSource *event_source = (MBWMManagerEventSource *)source; + MBWMManager *wm = event_source->wm; + + gboolean retval; + + /* TODO: mb_wm_threads_enter (); */ + + *timeout = -1; + retval = check_xpending (wm); + + /* TODO: mb_wm_threads_leave (); */ + + return retval; +} + +static gboolean +mb_wm_manager_event_check (GSource *source) +{ + MBWMManagerEventSource *event_source = (MBWMManagerEventSource *)source; + MBWMManager *wm = event_source->wm; + gboolean retval; + + /* TODO: mb_wm_threads_enter (); */ + + if (event_source->event_poll_fd.revents & G_IO_IN) + retval = check_xpending (wm); + else + retval = FALSE; + + /* TODO: mb_wm_threads_leave (); */ + + return retval; +} + +static gboolean +event_translate (MBWMManager *wm, + XEvent *xevent) +{ + GList *l; + + for (l = wm->xlib_event_filters; l; l = l->next) + { + MBWMXlibFilterClosure *closure = l->data; + if (closure->filter (xevent, closure->data) == MB_WM_XLIB_FILTER_REMOVE) + return FALSE; + } + + return TRUE; +} + +static gboolean +queue_event (MBWMManager *wm, XEvent *xevent) +{ + if (event_translate (wm, xevent)) + { + XEvent *copy = g_slice_copy (sizeof (XEvent), xevent); + /* push directly here to avoid copy of queue_put */ + g_queue_push_head (wm->event_queue, copy); + mb_wm_manager_queue_update (wm); + return TRUE; + } + else + return FALSE; +} + +gboolean +mb_wm_manager_handle_xlib_event (MBWMManager *wm, XEvent *xev) +{ + return queue_event (wm, xev); +} + +static void +queue_events (MBWMManager *wm) +{ + Display *xdisplay = wm->xdpy; + + while (XPending (xdisplay)) + { + XEvent xevent; + XNextEvent (xdisplay, &xevent); + + queue_event (wm, &xevent); + } +} + +static gboolean +mb_wm_manager_event_dispatch (GSource *source, + GSourceFunc callback, + void *user_data) +{ + MBWMManagerEventSource *event_source = (MBWMManagerEventSource *)source; + MBWMManager *wm = event_source->wm; + + /* TODO: mb_wm_threads_enter (); */ + + queue_events (wm); + + /* TODO: mb_wm_threads_leave (); */ + + return TRUE; +} + +static GSource * +mb_wm_manager_event_source_new (MBWMManager *wm) +{ + GSource *source = g_source_new (&event_funcs, + sizeof (MBWMManagerEventSource)); + MBWMManagerEventSource *event_source = (MBWMManagerEventSource *) source; + + event_source->wm = wm; + +#if GLIB_CHECK_VERSION (2, 25, 8) + g_source_set_name (source, "Matchbox X11 Event"); +#endif + + event_source->event_poll_fd.fd = ConnectionNumber (wm->xdpy); + event_source->event_poll_fd.events = G_IO_IN; + + g_source_add_poll (source, &event_source->event_poll_fd); + g_source_set_can_recurse (source, TRUE); + + return source; +} + +void +mb_wm_manager_disable_x11_event_retrieval (MBWMManager *wm) +{ + wm->event_retrieval_disabled = TRUE; +} + +void +mb_wm_manager_xlib_add_filter (MBWMManager *wm, + MBWMXlibFilterFunc filter, + void *data) +{ + MBWMXlibFilterClosure *closure; + + closure = g_slice_new (MBWMXlibFilterClosure); + closure->filter = filter; + closure->data = data; + + wm->xlib_event_filters = g_list_prepend (wm->xlib_event_filters, closure); +} + +void +mv_wm_manager_xlib_remove_filter (MBWMManager *wm, + MBWMXlibFilterFunc func, + void *data) +{ + GList *l; + + for (l = wm->xlib_event_filters; l; l = l->next) + { + MBWMXlibFilterClosure *closure = l->data; + + if (closure->filter == func && closure->data == data) + { + g_slice_free (MBWMXlibFilterClosure, closure); + wm->xlib_event_filters = + g_list_delete_link (wm->xlib_event_filters, l); + return; + } + } +} + /* * This function must be called before the MBWMManager object can be * used. */ static void -_mb_wm_manager_run (MBWMManager * wm, MBWMCompMgr *compositor) +_mb_wm_manager_start (MBWMManager * wm, MBWMCompMgr *compositor) { MBWMManagerClass *wm_class; + if (!wm->event_retrieval_disabled) + { + wm->event_source = mb_wm_manager_event_source_new (wm); + g_source_attach (wm->event_source, NULL); + } + wm_class = (MBWMManagerClass *) MB_WM_OBJECT_GET_CLASS (wm); mb_wm_manager_set_theme_from_path (wm, wm->theme_path); @@ -1537,16 +2252,16 @@ _mb_wm_manager_run (MBWMManager * wm, MBWMCompMgr *compositor) } void -mb_wm_manager_run (MBWMManager *window_manager) +mb_wm_manager_start (MBWMManager *window_manager) { - _mb_wm_manager_run (window_manager, NULL); + _mb_wm_manager_start (window_manager, NULL); } void -mb_wm_manager_run_with_compositor (MBWMManager *window_manager, +mb_wm_manager_start_with_compositor (MBWMManager *window_manager, MBWMCompMgr *compositor) { - _mb_wm_manager_run (window_manager, compositor); + _mb_wm_manager_start (window_manager, compositor); } @@ -1602,6 +2317,8 @@ mb_wm_manager_init (MBWMObject *this, va_list vap) mb_wm_atoms_init(wm); + wm->event_queue = g_queue_new (); + #if ENABLE_COMPOSITE if (!mb_wm_manager_init_comp_extensions (wm)) return 0; @@ -1611,65 +2328,63 @@ mb_wm_manager_init (MBWMObject *this, va_list vap) mb_wm_update_root_win_rectangles (wm); - wm->main_ctx = mb_wm_main_context_new (wm); - - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, None, MapRequest, (MBWMXEventFunc)mb_wm_handle_map_request, wm); #if ENABLE_COMPOSITE - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, None, MapNotify, (MBWMXEventFunc)mb_wm_handle_map_notify, wm); - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, None, ConfigureNotify, (MBWMXEventFunc)mb_wm_handle_composite_config_notify, wm); #endif - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, wm->root_win->xwindow, ConfigureNotify, (MBWMXEventFunc)mb_wm_handle_root_config_notify, wm); - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, None, ConfigureRequest, (MBWMXEventFunc)mb_wm_handle_config_request, wm); - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, None, PropertyNotify, (MBWMXEventFunc)mb_wm_handle_property_notify, wm); - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, None, DestroyNotify, (MBWMXEventFunc)mb_wm_handle_destroy_notify, wm); - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, None, UnmapNotify, (MBWMXEventFunc)mb_wm_handle_unmap_notify, wm); - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, None, KeyPress, (MBWMXEventFunc)mb_wm_handle_key_press, wm); - mb_wm_main_context_x_event_handler_add (wm->main_ctx, + mb_wm_manager_add_event_handler (wm, None, ButtonPress, (MBWMXEventFunc)mb_wm_handle_button_press, diff --git a/matchbox/mb-wm-manager.h b/matchbox/mb-wm-manager.h index 72a27a2..4f143ab 100644 --- a/matchbox/mb-wm-manager.h +++ b/matchbox/mb-wm-manager.h @@ -22,24 +22,17 @@ #define _HAVE_MB_WM_MANAGER_H #include <matchbox/mb-wm-config.h> +#include <matchbox/mb-wm-types.h> #include <matchbox/mb-wm-object.h> #include <matchbox/mb-wm-keys.h> #include <matchbox/mb-wm-root-window.h> #include <matchbox/mb-wm-theme.h> #include <matchbox/mb-wm-layout.h> -#include <matchbox/mb-wm-main-context.h> #if ENABLE_COMPOSITE #include <matchbox/mb-wm-comp-mgr.h> #endif #include <matchbox/xas.h> -/* XXX: we have a circular dependency between mb-wm-main-context.h - * and mb-window-manager.h */ -#ifndef MB_WM_MAIN_CONTEXT_TYPEDEF_DEFINED -typedef struct MBWMMainContext MBWMMainContext; -#define MB_WM_MAIN_CONTEXT_TYPEDEF_DEFINED -#endif - #define MB_WM_MANAGER(c) ((MBWMManager*)(c)) #define MB_WM_MANAGER_CLASS(c) ((MBWMManagerClass*)(c)) #define MB_WM_TYPE_MANAGER (mb_wm_manager_class_type ()) @@ -66,6 +59,28 @@ typedef enum _MBWMManagerCursorLast } MBWMManagerCursor; +typedef Bool (*MBWMManagerEventFunc) (XEvent * xev, void * userdata); + +typedef struct MBWMEventFuncs +{ + /* FIXME: figure our X wrap / unwrap mechanism */ + GList *map_notify; + GList *unmap_notify; + GList *map_request; + GList *destroy_notify; + GList *configure_request; + GList *configure_notify; + GList *key_press; + GList *property_notify; + GList *button_press; + GList *button_release; + GList *motion_notify; + GList *client_message; + +#if ENABLE_COMPOSITE + GList *damage_notify; +#endif +} MBWMEventFuncs; struct MBWMManager { @@ -75,6 +90,13 @@ struct MBWMManager unsigned int xdpy_width, xdpy_height; int xscreen; + GList *xlib_event_filters; + GQueue *event_queue; + gboolean event_retrieval_disabled; + GSource *event_source; + unsigned int do_update_idle; + MBWMEventFuncs event_funcs; + MBWindowManagerClient *stack_top, *stack_bottom; GList *clients; MBWindowManagerClient *desktop; @@ -99,7 +121,6 @@ struct MBWMManager MBWMTheme *theme; MBWMLayout *layout; - MBWMMainContext *main_ctx; MBWMManagerFlag flags; #if ENABLE_COMPOSITE MBWMCompMgr *comp_mgr; @@ -136,8 +157,6 @@ struct MBWMManagerClass MBWMTheme * (*theme_new) (MBWMManager *wm, const char * path); void (*get_desktop_geometry) (MBWMManager *wm, MBGeometry *geom); - - void (*main) (MBWMManager *wm); }; /** @@ -157,10 +176,26 @@ MBWMManager * mb_wm_manager_new_with_dpy (int argc, char **argv, Display * dpy); void -mb_wm_manager_run (MBWMManager * wm); +mb_wm_manager_disable_x11_event_retrieval (MBWMManager *wm); void -mb_wm_manager_run_with_compositor (MBWMManager * wm, MBWMCompMgr *compositor); +mb_wm_manager_xlib_add_filter (MBWMManager *wm, + MBWMXlibFilterFunc filter, + void *data); + +void +mv_wm_manager_xlib_remove_filter (MBWMManager *wm, + MBWMXlibFilterFunc func, + void *data); + +gboolean +mb_wm_manager_handle_xlib_event (MBWMManager *wm, XEvent *xev); + +void +mb_wm_manager_start (MBWMManager * wm); + +void +mb_wm_manager_start_with_compositor (MBWMManager * wm, MBWMCompMgr *compositor); void mb_wm_manager_set_layout (MBWMManager *wm, MBWMLayout *layout); @@ -242,6 +277,18 @@ mb_wm_manager_compositing_enabled (MBWMManager * wm); MBWMModality mb_wm_manager_get_modality_type (MBWMManager * wm); +unsigned long +mb_wm_manager_add_event_handler (MBWMManager *wm, + Window xwin, + int type, + MBWMXEventFunc func, + void *userdata); + +void +mb_wm_manager_remove_event_handler (MBWMManager *wm, + int type, + unsigned long id); + void mb_wm_manager_sync (MBWMManager *wm); diff --git a/matchbox/mb-wm-object.h b/matchbox/mb-wm-object.h index e43a45e..e4abb2a 100644 --- a/matchbox/mb-wm-object.h +++ b/matchbox/mb-wm-object.h @@ -22,6 +22,8 @@ #define _HAVE_MB_OBJECT_H #include <stdarg.h> +#include <glib.h> + #include <matchbox/mb-wm-object-props.h> typedef struct MBWMObject MBWMObject; diff --git a/matchbox/mb-wm-types.h b/matchbox/mb-wm-types.h index 5111f2b..0e8b503 100644 --- a/matchbox/mb-wm-types.h +++ b/matchbox/mb-wm-types.h @@ -382,4 +382,28 @@ typedef enum MBWMModality #define MB_CMD_COMPOSITE 8 #define MB_CMB_KEYS_RELOAD 9 +/** + * MBWMXlibFilterReturn: + * @MB_WM_XLIB_FILTER_CONTINUE: The event was not handled, continues the + * processing + * @MB_WM_XLIB_FILTER_REMOVE: Remove the event, stops the processing + * + * Return values for the #MBWMXlibFilterFunc function. + */ +typedef enum _MBWMXlibFilterReturn { + MB_WM_XLIB_FILTER_CONTINUE, + MB_WM_XLIB_FILTER_REMOVE +} MBWMXlibFilterReturn; + +/** + * MBWMXlibFilterFunc: + * + * A callback function that can be registered with + * _mb_wm_manager_xlib_add_filter. The function should return + * %MB_WM_XLIB_FILTER_REMOVE if it wants to prevent further processing + * or %MB_WM_XLIB_FILTER_CONTINUE otherwise. + */ +typedef MBWMXlibFilterReturn (* MBWMXlibFilterFunc) (XEvent *xevent, + void *data); + #endif |