aboutsummaryrefslogtreecommitdiffstats
path: root/matchbox/mb-wm-client-menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'matchbox/mb-wm-client-menu.c')
-rw-r--r--matchbox/mb-wm-client-menu.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/matchbox/mb-wm-client-menu.c b/matchbox/mb-wm-client-menu.c
new file mode 100644
index 0000000..b68f771
--- /dev/null
+++ b/matchbox/mb-wm-client-menu.c
@@ -0,0 +1,156 @@
+#include "mb-wm-client-menu.h"
+
+#include "mb-wm-theme.h"
+
+static Bool
+mb_wm_client_menu_request_geometry (MBWindowManagerClient *client,
+ MBGeometry *new_geometry,
+ MBWMClientReqGeomType flags);
+
+static void
+mb_wm_client_menu_realize (MBWindowManagerClient *client)
+{
+ /*
+ * Must reparent the window to our root, otherwise we restacking of
+ * pre-existing windows might fail.
+ */
+ XReparentWindow(client->wmref->xdpy, MB_WM_CLIENT_XWIN(client),
+ client->wmref->root_win->xwindow, 0, 0);
+}
+
+static void
+mb_wm_client_menu_class_init (MBWMObjectClass *klass)
+{
+ MBWindowManagerClientClass *client;
+
+ MBWM_MARK();
+
+ client = (MBWindowManagerClientClass *)klass;
+
+ client->client_type = MBWMClientTypeMenu;
+ client->geometry = mb_wm_client_menu_request_geometry;
+ client->realize = mb_wm_client_menu_realize;
+
+#if MBWM_WANT_DEBUG
+ klass->klass_name = "MBWMClientMenu";
+#endif
+}
+
+static void
+mb_wm_client_menu_destroy (MBWMObject *this)
+{
+}
+
+static int
+mb_wm_client_menu_init (MBWMObject *this, va_list vap)
+{
+ MBWindowManagerClient *client = MB_WM_CLIENT (this);
+ MBWindowManager *wm = client->wmref;
+ MBWMClientWindow *win = client->window;
+ Atom actions[] = {
+ wm->atoms[MBWM_ATOM_NET_WM_ACTION_CLOSE],
+ wm->atoms[MBWM_ATOM_NET_WM_ACTION_MOVE],
+ wm->atoms[MBWM_ATOM_NET_WM_ACTION_RESIZE],
+ };
+
+ XChangeProperty (wm->xdpy, win->xwindow,
+ wm->atoms[MBWM_ATOM_NET_WM_ALLOWED_ACTIONS],
+ XA_ATOM, 32, PropModeReplace,
+ (unsigned char *)actions,
+ sizeof (actions)/sizeof (actions[0]));
+
+ mb_wm_client_set_layout_hints (client,
+ LayoutPrefPositionFree|LayoutPrefVisible|
+ LayoutPrefFixedX|LayoutPrefFixedY);
+
+ /*
+ * Stack menus on the top of the stacking order, regardless of whether they
+ * declare themselves transient or not.
+ *
+ * (Gtk menus do kbd and pointer grabs and do not take kindly to being
+ * restacked.)
+ */
+#if 0
+ if (win->xwin_transient_for
+ && win->xwin_transient_for != win->xwindow
+ && win->xwin_transient_for != wm->root_win->xwindow)
+ {
+ MBWM_DBG ("Adding to '%lx' transient list",
+ win->xwin_transient_for);
+ mb_wm_client_add_transient
+ (mb_wm_managed_client_from_xwindow (wm,
+ win->xwin_transient_for),
+ client);
+ client->stacking_layer = 0; /* We stack with whatever transient too */
+ }
+ else
+ {
+ MBWM_DBG ("Menu is transient to root");
+ /* Stack with 'always on top' */
+ client->stacking_layer = MBWMStackLayerTopMid;
+ }
+#else
+ client->stacking_layer = MBWMStackLayerTop;
+#endif
+
+ return 1;
+}
+
+int
+mb_wm_client_menu_class_type ()
+{
+ static int type = 0;
+
+ if (UNLIKELY(type == 0))
+ {
+ static MBWMObjectClassInfo info = {
+ sizeof (MBWMClientMenuClass),
+ sizeof (MBWMClientMenu),
+ mb_wm_client_menu_init,
+ mb_wm_client_menu_destroy,
+ mb_wm_client_menu_class_init
+ };
+
+ type = mb_wm_object_register_class (&info, MB_WM_TYPE_CLIENT_BASE, 0);
+ }
+
+ return type;
+}
+
+static Bool
+mb_wm_client_menu_request_geometry (MBWindowManagerClient *client,
+ MBGeometry *new_geometry,
+ MBWMClientReqGeomType flags)
+{
+ if (client->window->geometry.x != new_geometry->x
+ || client->window->geometry.y != new_geometry->y
+ || client->window->geometry.width != new_geometry->width
+ || client->window->geometry.height != new_geometry->height)
+ {
+ client->window->geometry.x = new_geometry->x;
+ client->window->geometry.y = new_geometry->y;
+ client->window->geometry.width = new_geometry->width;
+ client->window->geometry.height = new_geometry->height;
+
+ mb_wm_client_geometry_mark_dirty (client);
+
+ return True; /* Geometry accepted */
+ }
+
+ return True; /* Geometry accepted */
+}
+
+MBWindowManagerClient*
+mb_wm_client_menu_new (MBWindowManager *wm, MBWMClientWindow *win)
+{
+ MBWindowManagerClient *client;
+
+ client
+ = MB_WM_CLIENT(mb_wm_object_new (MB_WM_TYPE_CLIENT_MENU,
+ MBWMObjectPropWm, wm,
+ MBWMObjectPropClientWindow, win,
+ NULL));
+
+ return client;
+}
+