#include "mb-wm-window-type-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); MBWMManager *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_manager_managed_window_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_WINDOW_TYPE_SIMPLE, 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 (MBWMManager *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; }