1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 window.c for the Openbox window manager
4 Copyright (c) 2003-2007 Dana Jansens
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 See the COPYING file for a copy of the GNU General Public License.
20 #include "menuframe.h"
30 #include "obt/xqueue.h"
32 static GHashTable
*window_map
;
34 static guint
window_hash(Window
*w
) { return *w
; }
35 static gboolean
window_comp(Window
*w1
, Window
*w2
) { return *w1
== *w2
; }
37 void window_startup(gboolean reconfig
)
41 window_map
= g_hash_table_new((GHashFunc
)window_hash
,
42 (GEqualFunc
)window_comp
);
45 void window_shutdown(gboolean reconfig
)
49 g_hash_table_destroy(window_map
);
52 Window
window_top(ObWindow
*self
)
55 case OB_WINDOW_CLASS_MENUFRAME
:
56 return WINDOW_AS_MENUFRAME(self
)->window
;
57 case OB_WINDOW_CLASS_DOCK
:
58 return WINDOW_AS_DOCK(self
)->frame
;
59 case OB_WINDOW_CLASS_CLIENT
:
60 return WINDOW_AS_CLIENT(self
)->frame
->window
;
61 case OB_WINDOW_CLASS_INTERNAL
:
62 return WINDOW_AS_INTERNAL(self
)->window
;
63 case OB_WINDOW_CLASS_PROMPT
:
64 return WINDOW_AS_PROMPT(self
)->super
.window
;
66 g_assert_not_reached();
70 ObStackingLayer
window_layer(ObWindow
*self
)
73 case OB_WINDOW_CLASS_DOCK
:
74 return config_dock_layer
;
75 case OB_WINDOW_CLASS_CLIENT
:
76 return ((ObClient
*)self
)->layer
;
77 case OB_WINDOW_CLASS_MENUFRAME
:
78 case OB_WINDOW_CLASS_INTERNAL
:
79 return OB_STACKING_LAYER_INTERNAL
;
80 case OB_WINDOW_CLASS_PROMPT
:
81 /* not used directly for stacking, prompts are managed as clients */
82 g_assert_not_reached();
85 g_assert_not_reached();
89 ObWindow
* window_find(Window xwin
)
91 return g_hash_table_lookup(window_map
, &xwin
);
94 void window_add(Window
*xwin
, ObWindow
*win
)
96 g_assert(xwin
!= NULL
);
97 g_assert(win
!= NULL
);
98 g_hash_table_insert(window_map
, xwin
, win
);
101 void window_remove(Window xwin
)
103 g_assert(xwin
!= None
);
104 g_hash_table_remove(window_map
, &xwin
);
107 void window_manage_all(void)
112 XWindowAttributes attrib
;
114 if (!XQueryTree(obt_display
, RootWindow(obt_display
, ob_screen
),
115 &w
, &w
, &children
, &nchild
)) {
116 ob_debug("XQueryTree failed in window_manage_all");
120 /* remove all icon windows from the list */
121 for (i
= 0; i
< nchild
; i
++) {
122 if (children
[i
] == None
) continue;
123 wmhints
= XGetWMHints(obt_display
, children
[i
]);
125 if ((wmhints
->flags
& IconWindowHint
) &&
126 (wmhints
->icon_window
!= children
[i
]))
127 for (j
= 0; j
< nchild
; j
++)
128 if (children
[j
] == wmhints
->icon_window
) {
129 /* XXX watch the window though */
137 for (i
= 0; i
< nchild
; ++i
) {
138 if (children
[i
] == None
) continue;
139 if (window_find(children
[i
])) continue; /* skip our own windows */
140 if (XGetWindowAttributes(obt_display
, children
[i
], &attrib
)) {
141 if (attrib
.map_state
== IsUnmapped
)
144 window_manage(children
[i
]);
148 if (children
) XFree(children
);
151 static gboolean
check_unmap(XEvent
*e
, gpointer data
)
153 const Window win
= *(Window
*)data
;
154 return ((e
->type
== DestroyNotify
&& e
->xdestroywindow
.window
== win
) ||
155 (e
->type
== UnmapNotify
&& e
->xunmap
.window
== win
));
158 void window_manage(Window win
)
160 XWindowAttributes attrib
;
161 gboolean no_manage
= FALSE
;
162 gboolean is_dockapp
= FALSE
;
163 Window icon_win
= None
;
167 /* check if it has already been unmapped by the time we started
168 mapping. the grab does a sync so we don't have to here */
169 if (xqueue_exists_local(check_unmap
, &win
)) {
170 ob_debug("Trying to manage unmapped window. Aborting that.");
173 else if (!XGetWindowAttributes(obt_display
, win
, &attrib
))
178 /* is the window a docking app */
180 if ((wmhints
= XGetWMHints(obt_display
, win
))) {
181 if ((wmhints
->flags
& StateHint
) &&
182 wmhints
->initial_state
== WithdrawnState
)
184 if (wmhints
->flags
& IconWindowHint
)
185 icon_win
= wmhints
->icon_window
;
190 /* This is a new method to declare that a window is a dockapp, being
191 implemented by Windowmaker, to alleviate pain in writing GTK+
193 http://thread.gmane.org/gmane.comp.window-managers.openbox/4881
197 if (OBT_PROP_GETSS_TYPE(win
, WM_CLASS
, STRING_NO_CC
, &ss
))
199 if (ss
[0] && ss
[1] && strcmp(ss
[1], "DockApp") == 0)
207 if (attrib
.override_redirect
) {
208 ob_debug("not managing override redirect window 0x%x", win
);
211 else if (is_dockapp
) {
214 dock_manage(icon_win
, win
);
217 client_manage(win
, NULL
);
221 ob_debug("FAILED to manage window 0x%x", win
);
225 void window_unmanage_all(void)
228 client_unmanage_all();