]> Dogcows Code - chaz/openbox/blob - openbox/popup.c
rename the Client struct to ObClient
[chaz/openbox] / openbox / popup.c
1 #include "openbox.h"
2 #include "frame.h"
3 #include "window.h"
4 #include "stacking.h"
5 #include "render/render.h"
6 #include "render/theme.h"
7
8 typedef struct Popup {
9 ObWindow obwin;
10 Window bg;
11
12 Window icon;
13 Window text;
14
15 gboolean hasicon;
16 RrAppearance *a_bg;
17 RrAppearance *a_icon;
18 RrAppearance *a_text;
19 int gravity;
20 int x;
21 int y;
22 int w;
23 int h;
24 gboolean mapped;
25 } Popup;
26
27 Popup *popup_new(gboolean hasicon)
28 {
29 XSetWindowAttributes attrib;
30 Popup *self = g_new(Popup, 1);
31
32 self->obwin.type = Window_Internal;
33 self->hasicon = hasicon;
34 self->a_text = NULL;
35 self->gravity = NorthWestGravity;
36 self->x = self->y = self->w = self->h = 0;
37 self->mapped = FALSE;
38 self->a_bg = self->a_icon = self->a_text = NULL;
39
40 attrib.override_redirect = True;
41 self->bg = XCreateWindow(ob_display, ob_root,
42 0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
43 InputOutput, RrVisual(ob_rr_inst),
44 CWOverrideRedirect, &attrib);
45
46 self->text = XCreateWindow(ob_display, self->bg,
47 0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
48 InputOutput, RrVisual(ob_rr_inst), 0, NULL);
49
50 if (self->hasicon)
51 self->icon = XCreateWindow(ob_display, self->bg,
52 0, 0, 1, 1, 0,
53 RrDepth(ob_rr_inst), InputOutput,
54 RrVisual(ob_rr_inst), 0, NULL);
55
56 XMapWindow(ob_display, self->text);
57 XMapWindow(ob_display, self->icon);
58
59 stacking_add(INTERNAL_AS_WINDOW(self));
60 return self;
61 }
62
63 void popup_free(Popup *self)
64 {
65 if (self) {
66 XDestroyWindow(ob_display, self->bg);
67 XDestroyWindow(ob_display, self->text);
68 XDestroyWindow(ob_display, self->icon);
69 RrAppearanceFree(self->a_bg);
70 RrAppearanceFree(self->a_icon);
71 RrAppearanceFree(self->a_text);
72 stacking_remove(self);
73 g_free(self);
74 }
75 }
76
77 void popup_position(Popup *self, int gravity, int x, int y)
78 {
79 self->gravity = gravity;
80 self->x = x;
81 self->y = y;
82 }
83
84 void popup_size(Popup *self, int w, int h)
85 {
86 self->w = w;
87 self->h = h;
88 }
89
90 void popup_size_to_string(Popup *self, char *text)
91 {
92 int textw, texth;
93 int iconw;
94
95 if (!self->a_text)
96 self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label);
97
98 self->a_text->texture[0].data.text.string = text;
99 RrMinsize(self->a_text, &textw, &texth);
100 textw += ob_rr_theme->bevel * 2;
101 texth += ob_rr_theme->bevel * 2;
102
103 self->h = texth + ob_rr_theme->bevel * 2;
104 iconw = (self->hasicon ? texth : 0);
105 self->w = textw + iconw + ob_rr_theme->bevel * (self->hasicon ? 3 : 2);
106 }
107
108 void popup_show(Popup *self, char *text, ObClientIcon *icon)
109 {
110 int x, y, w, h;
111 int textw, texth;
112 int iconw;
113
114 /* create the shit if needed */
115 if (!self->a_bg)
116 self->a_bg = RrAppearanceCopy(ob_rr_theme->app_hilite_bg);
117 if (self->hasicon && !self->a_icon)
118 self->a_icon = RrAppearanceCopy(ob_rr_theme->app_icon);
119 if (!self->a_text)
120 self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label);
121
122 XSetWindowBorderWidth(ob_display, self->bg, ob_rr_theme->bwidth);
123 XSetWindowBorder(ob_display, self->bg, ob_rr_theme->b_color->pixel);
124
125 /* set up the textures */
126 self->a_text->texture[0].data.text.string = text;
127 if (self->hasicon) {
128 if (icon) {
129 self->a_icon->texture[0].type = RR_TEXTURE_RGBA;
130 self->a_icon->texture[0].data.rgba.width = icon->width;
131 self->a_icon->texture[0].data.rgba.height = icon->height;
132 self->a_icon->texture[0].data.rgba.data = icon->data;
133 } else
134 self->a_icon->texture[0].type = RR_TEXTURE_NONE;
135 }
136
137 /* measure the shit out */
138 RrMinsize(self->a_text, &textw, &texth);
139 textw += ob_rr_theme->bevel * 2;
140 texth += ob_rr_theme->bevel * 2;
141
142 /* set the sizes up and reget the text sizes from the calculated
143 outer sizes */
144 if (self->h) {
145 h = self->h;
146 texth = h - (ob_rr_theme->bevel * 2);
147 } else
148 h = texth + ob_rr_theme->bevel * 2;
149 iconw = (self->hasicon ? texth : 0);
150 if (self->w) {
151 w = self->w;
152 textw = w - (iconw + ob_rr_theme->bevel * (self->hasicon ? 3 : 2));
153 } else
154 w = textw + iconw + ob_rr_theme->bevel * (self->hasicon ? 3 : 2);
155 /* sanity checks to avoid crashes! */
156 if (w < 1) w = 1;
157 if (h < 1) h = 1;
158 if (textw < 1) textw = 1;
159 if (texth < 1) texth = 1;
160
161 /* set up the x coord */
162 x = self->x;
163 switch (self->gravity) {
164 case NorthGravity:
165 case CenterGravity:
166 case SouthGravity:
167 x -= w / 2;
168 break;
169 case NorthEastGravity:
170 case EastGravity:
171 case SouthEastGravity:
172 x -= w;
173 break;
174 }
175
176 /* set up the y coord */
177 y = self->y;
178 switch (self->gravity) {
179 case WestGravity:
180 case CenterGravity:
181 case EastGravity:
182 y -= h / 2;
183 break;
184 case SouthWestGravity:
185 case SouthGravity:
186 case SouthEastGravity:
187 y -= h;
188 break;
189 }
190
191 /* set the windows/appearances up */
192 XMoveResizeWindow(ob_display, self->bg, x, y, w, h);
193
194 self->a_text->surface.parent = self->a_bg;
195 self->a_text->surface.parentx = iconw +
196 ob_rr_theme->bevel * (self->hasicon ? 2 : 1);
197 self->a_text->surface.parenty = ob_rr_theme->bevel;
198 XMoveResizeWindow(ob_display, self->text,
199 iconw + ob_rr_theme->bevel * (self->hasicon ? 2 : 1),
200 ob_rr_theme->bevel, textw, texth);
201
202 if (self->hasicon) {
203 if (iconw < 1) iconw = 1; /* sanity check for crashes */
204 self->a_icon->surface.parent = self->a_bg;
205 self->a_icon->surface.parentx = ob_rr_theme->bevel;
206 self->a_icon->surface.parenty = ob_rr_theme->bevel;
207 XMoveResizeWindow(ob_display, self->icon,
208 ob_rr_theme->bevel, ob_rr_theme->bevel,
209 iconw, texth);
210 }
211
212 RrPaint(self->a_bg, self->bg, w, h);
213 RrPaint(self->a_text, self->text, textw, texth);
214 if (self->hasicon)
215 RrPaint(self->a_icon, self->icon, iconw, texth);
216
217 if (!self->mapped) {
218 XMapWindow(ob_display, self->bg);
219 stacking_raise(INTERNAL_AS_WINDOW(self));
220 self->mapped = TRUE;
221 }
222 }
223
224 void popup_hide(Popup *self)
225 {
226 if (self->mapped) {
227 XUnmapWindow(ob_display, self->bg);
228 self->mapped = FALSE;
229 }
230 }
This page took 0.04869 seconds and 5 git commands to generate.