aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac28
-rw-r--r--doc/MBWM2-Overview.xml15
-rw-r--r--managers/clutter/matchbox-window-manager-2-clutter.c38
-rw-r--r--managers/maemo/matchbox-window-manager-2-maemo.c2
-rw-r--r--managers/simple/matchbox-window-manager-2-simple.c13
-rw-r--r--managers/xrender/matchbox-window-manager-2-xrender.c15
-rw-r--r--matchbox/Makefile.am2
-rw-r--r--matchbox/matchbox.h1
-rw-r--r--matchbox/mb-wm-client.c11
-rw-r--r--matchbox/mb-wm-comp-mgr.c4
-rw-r--r--matchbox/mb-wm-config.h.in6
-rw-r--r--matchbox/mb-wm-decor.c541
-rw-r--r--matchbox/mb-wm-decor.h3
-rw-r--r--matchbox/mb-wm-main-context.c1116
-rw-r--r--matchbox/mb-wm-main-context.h150
-rw-r--r--matchbox/mb-wm-manager.c991
-rw-r--r--matchbox/mb-wm-manager.h73
-rw-r--r--matchbox/mb-wm-object.h2
-rw-r--r--matchbox/mb-wm-types.h24
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 (&current_time, NULL);
-
- while (l)
- {
- MBWMTimeOutEventInfo * tinfo = l->data;
- unsigned long tid = tinfo->id;
-
- if (!mb_wm_main_context_handle_timeout (tinfo, &current_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 (&current_time, NULL);
- mb_wm_main_context_timeout_setup (tinfo, &current_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