4 #include "render/theme.h"
5 #include "render/render.h"
11 #define SLITAPP_EVENT_MASK (StructureNotifyMask)
16 /* user-requested position stuff */
21 /* actual position (when not auto-hidden) */
32 GHashTable
*slit_map
= NULL
;
37 static void slit_configure(Slit
*self
);
41 XSetWindowAttributes attrib
;
44 slit_map
= g_hash_table_new(g_int_hash
, g_int_equal
);
47 slit
= g_new0(struct Slit
, nslits
);
49 for (i
= 0; i
< nslits
; ++i
) {
52 attrib
.override_redirect
= True
;
53 slit
[i
].frame
= XCreateWindow(ob_display
, ob_root
, 0, 0, 1, 1, 0,
54 render_depth
, InputOutput
, render_visual
,
55 CWOverrideRedirect
, &attrib
);
56 slit
[i
].a_frame
= appearance_copy(theme_a_unfocused_title
);
57 XSetWindowBorder(ob_display
, slit
[i
].frame
, theme_b_color
->pixel
);
58 XSetWindowBorderWidth(ob_display
, slit
[i
].frame
, theme_bwidth
);
66 for (i
= 0; i
< nslits
; ++i
) {
67 XDestroyWindow(ob_display
, slit
[i
].frame
);
68 appearance_free(slit
[i
].a_frame
);
72 void slit_add(Window win
, XWMHints
*wmhints
, XWindowAttributes
*attrib
)
80 app
= g_new0(SlitApp
, 1);
83 app
->icon_win
= (wmhints
->flags
& IconWindowHint
) ?
84 wmhints
->icon_window
: win
;
86 app
->w
= attrib
->width
;
87 app
->h
= attrib
->height
;
89 s
->slit_apps
= g_list_append(s
->slit_apps
, app
);
91 XReparentWindow(ob_display
, app
->icon_win
, s
->frame
, app
->x
, app
->y
);
94 This is the same case as in frame.c for client windows. When Openbox is
95 starting, the window is already mapped so we see unmap events occur for
96 it. There are 2 unmap events generated that we see, one with the 'event'
97 member set the root window, and one set to the client, but both get
98 handled and need to be ignored.
100 if (ob_state
== State_Starting
)
101 app
->ignore_unmaps
+= 2;
103 if (app
->win
!= app
->icon_win
)
104 XMoveWindow(ob_display
, app
->win
, 100, 100);
105 XMapWindow(ob_display
, app
->icon_win
);
106 XSync(ob_display
, False
);
108 /* specify that if we exit, the window should not be destroyed and should
109 be reparented back to root automatically */
110 XChangeSaveSet(ob_display
, app
->icon_win
, SetModeInsert
);
111 XSelectInput(ob_display
, app
->icon_win
, SLITAPP_EVENT_MASK
);
113 g_hash_table_insert(slit_map
, &app
->icon_win
, app
);
115 g_message("Managed Slit App: 0x%lx", app
->icon_win
);
118 void slit_remove_all()
122 for (i
= 0; i
< nslits
; ++i
)
123 while (slit
[i
].slit_apps
)
124 slit_remove(slit
[i
].slit_apps
->data
, TRUE
);
127 void slit_remove(SlitApp
*app
, gboolean reparent
)
129 XSelectInput(ob_display
, app
->icon_win
, NoEventMask
);
130 /* remove the window from our save set */
131 XChangeSaveSet(ob_display
, app
->icon_win
, SetModeDelete
);
132 XSync(ob_display
, False
);
134 g_hash_table_remove(slit_map
, &app
->icon_win
);
137 XReparentWindow(ob_display
, app
->icon_win
, ob_root
, app
->x
, app
->y
);
139 app
->slit
->slit_apps
= g_list_remove(app
->slit
->slit_apps
, app
);
140 slit_configure(app
->slit
);
142 g_message("Unmanaged Slit App: 0x%lx", app
->icon_win
);
147 void slit_configure_all()
149 int i
; for (i
= 0; i
< nslits
; ++i
) slit_configure(&slit
[i
]);
152 static void slit_configure(Slit
*self
)
157 self
->w
= self
->h
= spot
= 0;
159 for (it
= self
->slit_apps
; it
; it
= it
->next
) {
160 struct SlitApp
*app
= it
->data
;
165 self
->h
= MAX(self
->h
, app
->h
);
170 self
->w
= MAX(self
->h
, app
->w
);
175 XMoveWindow(ob_display
, app
->icon_win
, app
->x
, app
->y
);
178 /* used for calculating offsets */
179 self
->w
+= theme_bwidth
* 2;
180 self
->h
+= theme_bwidth
* 2;
183 case SlitPos_Floating
:
184 /* calculate position */
185 self
->x
= self
->user_x
;
186 self
->y
= self
->user_y
;
188 switch(self
->gravity
) {
192 self
->x
-= self
->w
/ 2;
194 case NorthEastGravity
:
196 case SouthEastGravity
:
200 switch(self
->gravity
) {
204 self
->y
-= self
->h
/ 2;
206 case SouthWestGravity
:
208 case SouthEastGravity
:
213 case SlitPos_TopLeft
:
218 self
->x
= (screen_physical_size
.width
- self
->w
) / 2;
221 case SlitPos_TopRight
:
222 self
->x
= screen_physical_size
.width
- self
->w
;
227 self
->y
= (screen_physical_size
.height
- self
->h
) / 2;
230 self
->x
= screen_physical_size
.width
- self
->w
;
231 self
->y
= (screen_physical_size
.height
- self
->h
) / 2;
233 case SlitPos_BottomLeft
:
235 self
->y
= screen_physical_size
.height
- self
->h
;
238 self
->x
= (screen_physical_size
.width
- self
->w
) / 2;
239 self
->y
= screen_physical_size
.height
- self
->h
;
241 case SlitPos_BottomRight
:
242 self
->x
= screen_physical_size
.width
- self
->w
;
243 self
->y
= screen_physical_size
.height
- self
->h
;
247 /* not used for actually sizing shit */
248 self
->w
-= theme_bwidth
* 2;
249 self
->h
-= theme_bwidth
* 2;
251 if (self
->w
> 0 && self
->h
> 0) {
252 RECT_SET(self
->a_frame
->area
, 0, 0, self
->w
, self
->h
);
253 XMoveResizeWindow(ob_display
, self
->frame
,
254 self
->x
, self
->y
, self
->w
, self
->h
);
256 paint(self
->frame
, self
->a_frame
);
257 XMapWindow(ob_display
, self
->frame
);
259 XUnmapWindow(ob_display
, self
->frame
);