stacking_set_list();
}
-void client_manage_all(void)
-{
- guint i, j, nchild;
- Window w, *children;
- XWMHints *wmhints;
- XWindowAttributes attrib;
-
- XQueryTree(obt_display, RootWindow(obt_display, ob_screen),
- &w, &w, &children, &nchild);
-
- /* remove all icon windows from the list */
- for (i = 0; i < nchild; i++) {
- if (children[i] == None) continue;
- wmhints = XGetWMHints(obt_display, children[i]);
- if (wmhints) {
- if ((wmhints->flags & IconWindowHint) &&
- (wmhints->icon_window != children[i]))
- for (j = 0; j < nchild; j++)
- if (children[j] == wmhints->icon_window) {
- children[j] = None;
- break;
- }
- XFree(wmhints);
- }
- }
-
- /* manage windows in reverse order from how they were originally mapped.
- this is an attempt to manage children windows before their parents, so
- that when the parent is mapped, it can find the child */
- for (i = 0; i < nchild; ++i) {
- if (children[i] == None)
- continue;
- if (XGetWindowAttributes(obt_display, children[i], &attrib)) {
- if (attrib.override_redirect) continue;
-
- if (attrib.map_state != IsUnmapped)
- client_manage(children[i]);
- }
- }
- XFree(children);
-}
-
void client_manage(Window window)
{
ObClient *self;
- XEvent e;
- XWindowAttributes attrib;
XSetWindowAttributes attrib_set;
- XWMHints *wmhint;
gboolean activate = FALSE;
ObAppSettings *settings;
gboolean transient = FALSE;
Rect place, *monitor;
Time launch_time, map_time;
- grab_server(TRUE);
-
- /* check if it has already been unmapped by the time we started
- mapping. the grab does a sync so we don't have to here */
- if (XCheckTypedWindowEvent(obt_display, window, DestroyNotify, &e) ||
- XCheckTypedWindowEvent(obt_display, window, UnmapNotify, &e))
- {
- XPutBackEvent(obt_display, &e);
-
- ob_debug("Trying to manage unmapped window. Aborting that.\n");
- grab_server(FALSE);
- return; /* don't manage it */
- }
-
- /* make sure it isn't an override-redirect window */
- if (!XGetWindowAttributes(obt_display, window, &attrib) ||
- attrib.override_redirect)
- {
- grab_server(FALSE);
- return; /* don't manage it */
- }
-
- /* is the window a docking app */
- if ((wmhint = XGetWMHints(obt_display, window))) {
- if ((wmhint->flags & StateHint) &&
- wmhint->initial_state == WithdrawnState)
- {
- dock_add(window, wmhint);
- grab_server(FALSE);
- XFree(wmhint);
- return;
- }
- XFree(wmhint);
- }
-
ob_debug("Managing window: 0x%lx", window);
map_time = event_get_server_time();
ob_debug("Managed window 0x%lx plate 0x%x (%s)",
window, self->frame->window, self->class);
-
- return;
}
void client_add_destroy_notify(ObClientCallback func, gpointer data);
void client_remove_destroy_notify(ObClientCallback func);
-/*! Manages all existing windows */
-void client_manage_all();
-/*! Manages a given window
-*/
+/*! Manages a given window */
void client_manage(Window win);
/*! Unmanages all managed windows */
void client_unmanage_all();
}
}
+static guint window_hash(Window *w) { return *w; }
+static gboolean window_comp(Window *w1, Window *w2) { return *w1 == *w2; }
+
void dock_startup(gboolean reconfig)
{
XSetWindowAttributes attrib;
dock->hidden = TRUE;
+ dock->dock_map = g_hash_table_new((GHashFunc)window_hash,
+ (GEqualFunc)window_comp);
+
attrib.event_mask = DOCK_EVENT_MASK;
attrib.override_redirect = True;
attrib.do_not_propagate_mask = DOCK_NOPROPAGATEMASK;
return;
}
+ g_hash_table_destroy(dock->dock_map);
+
XDestroyWindow(obt_display, dock->frame);
RrAppearanceFree(dock->a_frame);
window_remove(dock->frame);
stacking_remove(dock);
}
-void dock_add(Window win, XWMHints *wmhints)
+void dock_manage(Window icon_win, Window name_win)
{
ObDockApp *app;
XWindowAttributes attrib;
gchar **data;
app = g_new0(ObDockApp, 1);
- app->win = win;
- app->icon_win = (wmhints->flags & IconWindowHint) ?
- wmhints->icon_window : win;
+ app->name_win = name_win;
+ app->icon_win = icon_win;
- if (OBT_PROP_GETSS(app->win, WM_CLASS, locale, &data)) {
+ if (OBT_PROP_GETSS(app->name_win, WM_CLASS, locale, &data)) {
if (data[0]) {
app->name = g_strdup(data[0]);
if (data[1])
}
dock->dock_apps = g_list_append(dock->dock_apps, app);
+ g_hash_table_insert(dock->dock_map, &app->icon_win, app);
dock_configure();
XReparentWindow(obt_display, app->icon_win, dock->frame, app->x, app->y);
*/
if (ob_state() == OB_STATE_STARTING)
app->ignore_unmaps += 2;
+ XChangeSaveSet(obt_display, app->icon_win, SetModeInsert);
+ XMapWindow(obt_display, app->icon_win);
- if (app->win != app->icon_win) {
- /* have to map it so that it can be re-managed on a restart */
- XMoveWindow(obt_display, app->win, -1000, -1000);
- XMapWindow(obt_display, app->win);
+ if (app->name_win != app->icon_win) {
+ XReparentWindow(obt_display, app->name_win, dock->frame, -1000, -1000);
+ XChangeSaveSet(obt_display, app->name_win, SetModeInsert);
+ XMapWindow(obt_display, app->name_win);
}
- XMapWindow(obt_display, app->icon_win);
+
XSync(obt_display, False);
- /* specify that if we exit, the window should not be destroyed and should
- be reparented back to root automatically */
- XChangeSaveSet(obt_display, app->icon_win, SetModeInsert);
XSelectInput(obt_display, app->icon_win, DOCKAPP_EVENT_MASK);
dock_app_grab_button(app, TRUE);
- ob_debug("Managed Dock App: 0x%lx (%s)", app->icon_win, app->class);
+ ob_debug("Managed Dock App: 0x%lx 0x%lx (%s)",
+ app->icon_win, app->name_win, app->class);
+
+ grab_server(FALSE);
}
-void dock_remove_all(void)
+void dock_unmanage_all(void)
{
while (dock->dock_apps)
- dock_remove(dock->dock_apps->data, TRUE);
+ dock_unmanage(dock->dock_apps->data, TRUE);
}
-void dock_remove(ObDockApp *app, gboolean reparent)
+void dock_unmanage(ObDockApp *app, gboolean reparent)
{
dock_app_grab_button(app, FALSE);
XSelectInput(obt_display, app->icon_win, NoEventMask);
XChangeSaveSet(obt_display, app->icon_win, SetModeDelete);
XSync(obt_display, False);
- if (reparent)
- XReparentWindow(obt_display, app->icon_win,
- obt_root(ob_screen), app->x, app->y);
+ if (reparent) {
+ XReparentWindow(obt_display, app->icon_win, obt_root(ob_screen), 0, 0);
+ if (app->name_win != app->icon_win)
+ XReparentWindow(obt_display, app->name_win,
+ obt_root(ob_screen), 0, 0);
+ }
dock->dock_apps = g_list_remove(dock->dock_apps, app);
+ g_hash_table_remove(dock->dock_map, &app->icon_win);
dock_configure();
ob_debug("Unmanaged Dock App: 0x%lx (%s)", app->icon_win, app->class);
ObDockApp* dock_find_dockapp(Window xwin)
{
- GList *it;
- /* there are never that many dock apps, so we can use a list here instead
- of a hash table */
- for (it = dock->dock_apps; it; it = g_list_next(it)) {
- ObDockApp *app = it->data;
- if (app->icon_win == xwin)
- return app;
- }
- return NULL;
+ return g_hash_table_lookup(dock->dock_map, &xwin);
}
gboolean hidden;
GList *dock_apps;
+ GHashTable *dock_map;
};
struct _ObDockApp {
gint ignore_unmaps;
Window icon_win;
- Window win;
+ Window name_win;
gchar *name;
gchar *class;
void dock_configure();
void dock_hide(gboolean hide);
-void dock_add(Window win, XWMHints *wmhints);
+void dock_manage(Window icon_win, Window name_win);
-void dock_remove_all();
-void dock_remove(ObDockApp *app, gboolean reparent);
+void dock_unmanage_all();
+void dock_unmanage(ObDockApp *app, gboolean reparent);
void dock_app_drag(ObDockApp *app, XMotionEvent *e);
void dock_app_configure(ObDockApp *app, gint w, gint h);
case SelectionClear:
window = obt_root(ob_screen);
break;
+ case CreateNotify:
+ window = e->xcreatewindow.window;
+ break;
case MapRequest:
+ window = e->xmaprequest.window;
+ break;
+ case MapNotify:
window = e->xmap.window;
break;
case UnmapNotify:
else if (window == obt_root(ob_screen))
event_handle_root(e);
else if (e->type == MapRequest)
- client_manage(window);
+ window_manage(window);
else if (e->type == MappingNotify) {
/* keyboard layout changes for modifier mapping changes. reload the
modifier map, and rebind all the key bindings as appropriate */
app->ignore_unmaps--;
break;
}
- dock_remove(app, TRUE);
+ dock_unmanage(app, TRUE);
break;
case DestroyNotify:
- dock_remove(app, FALSE);
+ dock_unmanage(app, FALSE);
break;
case ReparentNotify:
- dock_remove(app, FALSE);
+ dock_unmanage(app, FALSE);
break;
case ConfigureNotify:
dock_app_configure(app, e->xconfigure.width, e->xconfigure.height);
ObWindow *w;
/* get all the existing windows */
- client_manage_all();
+ window_manage_all();
focus_nothing();
/* focus what was focused if a wm was already running */
obt_main_loop_run(ob_main_loop);
state = OB_STATE_EXITING;
- if (!reconfigure) {
- dock_remove_all();
- client_unmanage_all();
- }
+ if (!reconfigure)
+ window_unmanage_all();
menu_shutdown(reconfigure);
menu_frame_shutdown(reconfigure);
#include "dock.h"
#include "client.h"
#include "frame.h"
+#include "openbox.h"
+#include "debug.h"
+#include "grab.h"
static GHashTable *window_map;
g_assert(xwin != None);
g_hash_table_remove(window_map, &xwin);
}
+
+void window_manage_all(void)
+{
+ guint i, j, nchild;
+ Window w, *children;
+ XWMHints *wmhints;
+ XWindowAttributes attrib;
+
+ if (!XQueryTree(obt_display, RootWindow(obt_display, ob_screen),
+ &w, &w, &children, &nchild)) {
+ ob_debug("XQueryTree failed in window_manage_all");
+ nchild = 0;
+ }
+
+ /* remove all icon windows from the list */
+ for (i = 0; i < nchild; i++) {
+ if (children[i] == None) continue;
+ wmhints = XGetWMHints(obt_display, children[i]);
+ if (wmhints) {
+ if ((wmhints->flags & IconWindowHint) &&
+ (wmhints->icon_window != children[i]))
+ for (j = 0; j < nchild; j++)
+ if (children[j] == wmhints->icon_window) {
+ /* XXX watch the window though */
+ children[j] = None;
+ break;
+ }
+ XFree(wmhints);
+ }
+ }
+
+ for (i = 0; i < nchild; ++i) {
+ if (children[i] == None) continue;
+ if (window_find(children[i])) continue; /* skip our own windows */
+ if (XGetWindowAttributes(obt_display, children[i], &attrib)) {
+ if (attrib.map_state == IsUnmapped)
+ ;
+ else
+ window_manage(children[i]);
+ }
+ }
+
+ if (children) XFree(children);
+}
+
+void window_manage(Window win)
+{
+ XEvent e;
+ XWindowAttributes attrib;
+ gboolean no_manage = FALSE;
+ gboolean is_dockapp = FALSE;
+ Window icon_win = None;
+
+ grab_server(TRUE);
+
+ /* check if it has already been unmapped by the time we started
+ mapping. the grab does a sync so we don't have to here */
+ if (XCheckTypedWindowEvent(obt_display, win, DestroyNotify, &e) ||
+ XCheckTypedWindowEvent(obt_display, win, UnmapNotify, &e))
+ {
+ XPutBackEvent(obt_display, &e);
+ ob_debug("Trying to manage unmapped window. Aborting that.\n");
+ no_manage = TRUE;
+ }
+
+ if (!XGetWindowAttributes(obt_display, win, &attrib))
+ no_manage = TRUE;
+ else {
+ XWMHints *wmhints;
+
+ /* is the window a docking app */
+ is_dockapp = FALSE;
+ if ((wmhints = XGetWMHints(obt_display, win))) {
+ if ((wmhints->flags & StateHint) &&
+ wmhints->initial_state == WithdrawnState)
+ {
+ if (wmhints->flags & IconWindowHint)
+ icon_win = wmhints->icon_window;
+ is_dockapp = TRUE;
+ }
+ XFree(wmhints);
+ }
+ }
+
+ if (!no_manage) {
+ if (attrib.override_redirect) {
+ ob_debug("not managing override redirect window 0x%x\n", win);
+ grab_server(FALSE);
+ }
+ else if (is_dockapp) {
+ if (!icon_win)
+ icon_win = win;
+ dock_manage(icon_win, win);
+ }
+ else
+ client_manage(win);
+ }
+ else {
+ grab_server(FALSE);
+ ob_debug("FAILED to manage window 0x%x\n", win);
+ }
+}
+
+void window_unmanage_all(void)
+{
+ dock_unmanage_all();
+ client_unmanage_all();
+}
Window window;
};
+void window_manage_all(void);
+void window_manage(Window win);
+void window_unmanage_all(void);
+
#endif