8 #include "render/render.h"
9 #include "render/theme.h"
11 ObPopup
*popup_new(gboolean hasicon
)
13 XSetWindowAttributes attrib
;
14 ObPopup
*self
= g_new0(ObPopup
, 1);
16 self
->obwin
.type
= Window_Internal
;
17 self
->hasicon
= hasicon
;
18 self
->gravity
= NorthWestGravity
;
19 self
->x
= self
->y
= self
->w
= self
->h
= 0;
20 self
->a_bg
= RrAppearanceCopy(ob_rr_theme
->app_hilite_bg
);
21 self
->a_text
= RrAppearanceCopy(ob_rr_theme
->app_hilite_label
);
23 attrib
.override_redirect
= True
;
24 self
->bg
= XCreateWindow(ob_display
, RootWindow(ob_display
, ob_screen
),
25 0, 0, 1, 1, 0, RrDepth(ob_rr_inst
),
26 InputOutput
, RrVisual(ob_rr_inst
),
27 CWOverrideRedirect
, &attrib
);
29 self
->text
= XCreateWindow(ob_display
, self
->bg
,
30 0, 0, 1, 1, 0, RrDepth(ob_rr_inst
),
31 InputOutput
, RrVisual(ob_rr_inst
), 0, NULL
);
33 XMapWindow(ob_display
, self
->text
);
35 stacking_add(INTERNAL_AS_WINDOW(self
));
39 void popup_free(ObPopup
*self
)
42 XDestroyWindow(ob_display
, self
->bg
);
43 XDestroyWindow(ob_display
, self
->text
);
44 RrAppearanceFree(self
->a_bg
);
45 RrAppearanceFree(self
->a_text
);
46 stacking_remove(self
);
51 void popup_position(ObPopup
*self
, gint gravity
, gint x
, gint y
)
53 self
->gravity
= gravity
;
58 void popup_size(ObPopup
*self
, gint w
, gint h
)
64 void popup_size_to_string(ObPopup
*self
, gchar
*text
)
69 self
->a_text
->texture
[0].data
.text
.string
= text
;
70 RrMinsize(self
->a_text
, &textw
, &texth
);
71 /*XXX textw += ob_rr_theme->bevel * 2;*/
72 texth
+= ob_rr_theme
->padding
* 2;
74 self
->h
= texth
+ ob_rr_theme
->padding
* 2;
75 iconw
= (self
->hasicon
? texth
: 0);
76 self
->w
= textw
+ iconw
+ ob_rr_theme
->padding
* (self
->hasicon
? 3 : 2);
79 void popup_set_text_align(ObPopup
*self
, RrJustify align
)
81 self
->a_text
->texture
[0].data
.text
.justify
= align
;
84 void popup_show(ObPopup
*self
, gchar
*text
)
91 RrMargins(self
->a_bg
, &l
, &t
, &r
, &b
);
93 XSetWindowBorderWidth(ob_display
, self
->bg
, ob_rr_theme
->bwidth
);
94 XSetWindowBorder(ob_display
, self
->bg
, ob_rr_theme
->b_color
->pixel
);
96 /* set up the textures */
97 self
->a_text
->texture
[0].data
.text
.string
= text
;
99 /* measure the shit out */
100 RrMinsize(self
->a_text
, &textw
, &texth
);
101 /*XXX textw += ob_rr_theme->padding * 2;*/
102 texth
+= ob_rr_theme
->padding
* 2;
104 /* set the sizes up and reget the text sizes from the calculated
108 texth
= h
- (t
+b
+ ob_rr_theme
->padding
* 2);
110 h
= t
+b
+ texth
+ ob_rr_theme
->padding
* 2;
111 iconw
= (self
->hasicon
? texth
: 0);
114 textw
= w
- (l
+r
+ iconw
+ ob_rr_theme
->padding
*
115 (self
->hasicon
? 3 : 2));
117 w
= l
+r
+ textw
+ iconw
+ ob_rr_theme
->padding
*
118 (self
->hasicon
? 3 : 2);
119 /* sanity checks to avoid crashes! */
122 if (textw
< 1) textw
= 1;
123 if (texth
< 1) texth
= 1;
125 /* set up the x coord */
127 switch (self
->gravity
) {
133 case NorthEastGravity
:
135 case SouthEastGravity
:
140 /* set up the y coord */
142 switch (self
->gravity
) {
148 case SouthWestGravity
:
150 case SouthEastGravity
:
155 /* set the windows/appearances up */
156 XMoveResizeWindow(ob_display
, self
->bg
, x
, y
, w
, h
);
158 self
->a_text
->surface
.parent
= self
->a_bg
;
159 self
->a_text
->surface
.parentx
= l
+ iconw
+
160 ob_rr_theme
->padding
* (self
->hasicon
? 2 : 1);
161 self
->a_text
->surface
.parenty
= t
+ ob_rr_theme
->padding
;
162 XMoveResizeWindow(ob_display
, self
->text
,
163 l
+ iconw
+ ob_rr_theme
->padding
*
164 (self
->hasicon
? 2 : 1),
165 t
+ ob_rr_theme
->padding
, textw
, texth
);
167 RrPaint(self
->a_bg
, self
->bg
, w
, h
);
168 RrPaint(self
->a_text
, self
->text
, textw
, texth
);
171 if (iconw
< 1) iconw
= 1; /* sanity check for crashes */
173 self
->draw_icon(l
+ ob_rr_theme
->padding
, t
+ ob_rr_theme
->padding
,
174 iconw
, texth
, self
->draw_icon_data
);
178 XMapWindow(ob_display
, self
->bg
);
179 stacking_raise(INTERNAL_AS_WINDOW(self
));
184 void popup_hide(ObPopup
*self
)
187 XUnmapWindow(ob_display
, self
->bg
);
188 self
->mapped
= FALSE
;
192 static void icon_popup_draw_icon(gint x
, gint y
, gint w
, gint h
, gpointer data
)
194 ObIconPopup
*self
= data
;
196 self
->a_icon
->surface
.parent
= self
->popup
->a_bg
;
197 self
->a_icon
->surface
.parentx
= x
;
198 self
->a_icon
->surface
.parenty
= y
;
199 XMoveResizeWindow(ob_display
, self
->icon
, x
, y
, w
, h
);
200 RrPaint(self
->a_icon
, self
->icon
, w
, h
);
203 ObIconPopup
*icon_popup_new()
207 self
= g_new0(ObIconPopup
, 1);
208 self
->popup
= popup_new(TRUE
);
209 self
->a_icon
= RrAppearanceCopy(ob_rr_theme
->a_clear_tex
);
210 self
->icon
= XCreateWindow(ob_display
, self
->popup
->bg
,
212 RrDepth(ob_rr_inst
), InputOutput
,
213 RrVisual(ob_rr_inst
), 0, NULL
);
214 XMapWindow(ob_display
, self
->icon
);
216 self
->popup
->draw_icon
= icon_popup_draw_icon
;
217 self
->popup
->draw_icon_data
= self
;
222 void icon_popup_free(ObIconPopup
*self
)
225 XDestroyWindow(ob_display
, self
->icon
);
226 RrAppearanceFree(self
->a_icon
);
227 popup_free(self
->popup
);
232 void icon_popup_show(ObIconPopup
*self
,
233 gchar
*text
, struct _ObClientIcon
*icon
)
236 self
->a_icon
->texture
[0].type
= RR_TEXTURE_RGBA
;
237 self
->a_icon
->texture
[0].data
.rgba
.width
= icon
->width
;
238 self
->a_icon
->texture
[0].data
.rgba
.height
= icon
->height
;
239 self
->a_icon
->texture
[0].data
.rgba
.data
= icon
->data
;
241 self
->a_icon
->texture
[0].type
= RR_TEXTURE_NONE
;
243 popup_show(self
->popup
, text
);
246 static void pager_popup_draw_icon(gint px
, gint py
, gint w
, gint h
,
249 ObPagerPopup
*self
= data
;
258 eachw
= (w
- ob_rr_theme
->bwidth
-
259 (screen_desktop_layout
.columns
* ob_rr_theme
->bwidth
))
260 / screen_desktop_layout
.columns
;
261 eachh
= (h
- ob_rr_theme
->bwidth
-
262 (screen_desktop_layout
.rows
* ob_rr_theme
->bwidth
))
263 / screen_desktop_layout
.rows
;
264 /* make them squares */
265 eachw
= eachh
= MIN(eachw
, eachh
);
266 g_message("dif %d %d %d %d ",
267 (screen_desktop_layout
.columns
* (eachw
+ ob_rr_theme
->bwidth
) +
268 ob_rr_theme
->bwidth
), w
,
269 (screen_desktop_layout
.rows
* (eachh
+ ob_rr_theme
->bwidth
) +
270 ob_rr_theme
->bwidth
), h
);
273 px
+= (w
- (screen_desktop_layout
.columns
* (eachw
+ ob_rr_theme
->bwidth
) +
274 ob_rr_theme
->bwidth
)) / 2;
275 py
+= (h
- (screen_desktop_layout
.rows
* (eachh
+ ob_rr_theme
->bwidth
) +
276 ob_rr_theme
->bwidth
)) / 2;
278 g_message("%d %d %d %d", px
, py
, eachw
, eachh
);
280 if (eachw
<= 0 || eachh
<= 0)
283 switch (screen_desktop_layout
.start_corner
) {
284 case OB_CORNER_TOPLEFT
:
286 switch (screen_desktop_layout
.orientation
) {
287 case OB_ORIENTATION_HORZ
:
289 vert_inc
= screen_desktop_layout
.columns
;
291 case OB_ORIENTATION_VERT
:
292 horz_inc
= screen_desktop_layout
.rows
;
297 case OB_CORNER_TOPRIGHT
:
298 n
= screen_desktop_layout
.columns
;
299 switch (screen_desktop_layout
.orientation
) {
300 case OB_ORIENTATION_HORZ
:
302 vert_inc
= screen_desktop_layout
.columns
;
304 case OB_ORIENTATION_VERT
:
305 horz_inc
= -screen_desktop_layout
.rows
;
310 case OB_CORNER_BOTTOMLEFT
:
311 n
= screen_desktop_layout
.rows
;
312 switch (screen_desktop_layout
.orientation
) {
313 case OB_ORIENTATION_HORZ
:
315 vert_inc
= -screen_desktop_layout
.columns
;
317 case OB_ORIENTATION_VERT
:
318 horz_inc
= screen_desktop_layout
.rows
;
323 case OB_CORNER_BOTTOMRIGHT
:
325 screen_desktop_layout
.rows
* screen_desktop_layout
.columns
);
326 switch (screen_desktop_layout
.orientation
) {
327 case OB_ORIENTATION_HORZ
:
329 vert_inc
= -screen_desktop_layout
.columns
;
331 case OB_ORIENTATION_VERT
:
332 horz_inc
= -screen_desktop_layout
.rows
;
339 g_message("%d %d %d", n
, horz_inc
, vert_inc
);
343 for (r
= 0, y
= 0; r
< screen_desktop_layout
.rows
;
344 ++r
, y
+= eachh
+ ob_rr_theme
->bwidth
)
346 for (c
= 0, x
= 0; c
< screen_desktop_layout
.columns
;
347 ++c
, x
+= eachw
+ ob_rr_theme
->bwidth
)
351 g_message("i %d n %d", i
, n
);
353 if (i
>= self
->desks
)
356 a
= (n
== self
->curdesk
? self
->hilight
: self
->unhilight
);
358 a
->surface
.parent
= self
->popup
->a_bg
;
359 a
->surface
.parentx
= x
+ px
;
360 a
->surface
.parenty
= y
+ py
;
361 XMoveResizeWindow(ob_display
, self
->wins
[i
],
362 x
+ px
, y
+ py
, eachw
, eachh
);
363 RrPaint(a
, self
->wins
[i
], eachw
, eachh
);
369 n
= rown
+= vert_inc
;
373 ObPagerPopup
*pager_popup_new()
377 self
= g_new(ObPagerPopup
, 1);
378 self
->popup
= popup_new(TRUE
);
381 self
->wins
= g_new(Window
, self
->desks
);
382 self
->hilight
= RrAppearanceCopy(ob_rr_theme
->app_hilite_fg
);
383 self
->unhilight
= RrAppearanceCopy(ob_rr_theme
->app_unhilite_fg
);
385 self
->popup
->draw_icon
= pager_popup_draw_icon
;
386 self
->popup
->draw_icon_data
= self
;
391 void pager_popup_free(ObPagerPopup
*self
)
396 for (i
= 0; i
< self
->desks
; ++i
)
397 XDestroyWindow(ob_display
, self
->wins
[i
]);
399 RrAppearanceFree(self
->hilight
);
400 RrAppearanceFree(self
->unhilight
);
401 popup_free(self
->popup
);
406 void pager_popup_show(ObPagerPopup
*self
, gchar
*text
, guint desk
)
410 if (screen_num_desktops
< self
->desks
)
411 for (i
= screen_num_desktops
; i
< self
->desks
; ++i
)
412 XDestroyWindow(ob_display
, self
->wins
[i
]);
414 if (screen_num_desktops
!= self
->desks
)
415 self
->wins
= g_renew(Window
, self
->wins
, screen_num_desktops
);
417 if (screen_num_desktops
> self
->desks
)
418 for (i
= self
->desks
; i
< screen_num_desktops
; ++i
) {
419 XSetWindowAttributes attr
;
421 attr
.border_pixel
= RrColorPixel(ob_rr_theme
->b_color
);
422 self
->wins
[i
] = XCreateWindow(ob_display
, self
->popup
->bg
,
423 0, 0, 1, 1, ob_rr_theme
->bwidth
,
424 RrDepth(ob_rr_inst
), InputOutput
,
425 RrVisual(ob_rr_inst
), CWBorderPixel
,
427 XMapWindow(ob_display
, self
->wins
[i
]);
430 self
->desks
= screen_num_desktops
;
431 self
->curdesk
= desk
;
433 popup_show(self
->popup
, text
);