2003-05-09 19:58:08 +00:00
|
|
|
#include "openbox.h"
|
|
|
|
#include "frame.h"
|
2003-07-10 07:16:19 +00:00
|
|
|
#include "client.h"
|
2003-05-11 23:31:43 +00:00
|
|
|
#include "window.h"
|
|
|
|
#include "stacking.h"
|
2003-05-09 19:58:08 +00:00
|
|
|
#include "render/render.h"
|
|
|
|
#include "render/theme.h"
|
|
|
|
|
|
|
|
typedef struct Popup {
|
2003-05-11 23:31:43 +00:00
|
|
|
ObWindow obwin;
|
2003-05-09 19:58:08 +00:00
|
|
|
Window bg;
|
2003-05-11 23:31:43 +00:00
|
|
|
|
2003-05-09 19:58:08 +00:00
|
|
|
Window icon;
|
|
|
|
Window text;
|
2003-05-11 23:31:43 +00:00
|
|
|
|
|
|
|
gboolean hasicon;
|
2003-06-21 00:42:47 +00:00
|
|
|
RrAppearance *a_bg;
|
|
|
|
RrAppearance *a_icon;
|
|
|
|
RrAppearance *a_text;
|
2003-05-09 19:58:08 +00:00
|
|
|
int gravity;
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
int w;
|
|
|
|
int h;
|
2003-05-11 23:31:43 +00:00
|
|
|
gboolean mapped;
|
2003-05-09 19:58:08 +00:00
|
|
|
} Popup;
|
|
|
|
|
|
|
|
Popup *popup_new(gboolean hasicon)
|
|
|
|
{
|
2003-06-29 17:18:19 +00:00
|
|
|
XSetWindowAttributes attrib;
|
2003-05-09 19:58:08 +00:00
|
|
|
Popup *self = g_new(Popup, 1);
|
2003-06-29 17:18:19 +00:00
|
|
|
|
2003-05-11 23:31:43 +00:00
|
|
|
self->obwin.type = Window_Internal;
|
2003-05-09 19:58:08 +00:00
|
|
|
self->hasicon = hasicon;
|
|
|
|
self->a_text = NULL;
|
|
|
|
self->gravity = NorthWestGravity;
|
|
|
|
self->x = self->y = self->w = self->h = 0;
|
2003-05-11 23:31:43 +00:00
|
|
|
self->mapped = FALSE;
|
2003-06-29 17:18:19 +00:00
|
|
|
self->a_bg = self->a_icon = self->a_text = NULL;
|
|
|
|
|
|
|
|
attrib.override_redirect = True;
|
|
|
|
self->bg = XCreateWindow(ob_display, ob_root,
|
|
|
|
0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
|
|
|
|
InputOutput, RrVisual(ob_rr_inst),
|
|
|
|
CWOverrideRedirect, &attrib);
|
|
|
|
|
|
|
|
self->text = XCreateWindow(ob_display, self->bg,
|
|
|
|
0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
|
|
|
|
InputOutput, RrVisual(ob_rr_inst), 0, NULL);
|
|
|
|
|
|
|
|
if (self->hasicon)
|
|
|
|
self->icon = XCreateWindow(ob_display, self->bg,
|
|
|
|
0, 0, 1, 1, 0,
|
|
|
|
RrDepth(ob_rr_inst), InputOutput,
|
|
|
|
RrVisual(ob_rr_inst), 0, NULL);
|
|
|
|
|
|
|
|
XMapWindow(ob_display, self->text);
|
|
|
|
XMapWindow(ob_display, self->icon);
|
|
|
|
|
2003-05-16 15:16:33 +00:00
|
|
|
stacking_add(INTERNAL_AS_WINDOW(self));
|
2003-05-09 19:58:08 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
void popup_free(Popup *self)
|
|
|
|
{
|
2003-06-29 17:18:19 +00:00
|
|
|
if (self) {
|
2003-05-09 19:58:08 +00:00
|
|
|
XDestroyWindow(ob_display, self->bg);
|
|
|
|
XDestroyWindow(ob_display, self->text);
|
|
|
|
XDestroyWindow(ob_display, self->icon);
|
2003-06-21 00:42:47 +00:00
|
|
|
RrAppearanceFree(self->a_bg);
|
2003-06-29 17:18:19 +00:00
|
|
|
RrAppearanceFree(self->a_icon);
|
2003-06-21 00:42:47 +00:00
|
|
|
RrAppearanceFree(self->a_text);
|
2003-06-29 17:18:19 +00:00
|
|
|
stacking_remove(self);
|
|
|
|
g_free(self);
|
|
|
|
}
|
2003-05-09 19:58:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void popup_position(Popup *self, int gravity, int x, int y)
|
|
|
|
{
|
|
|
|
self->gravity = gravity;
|
|
|
|
self->x = x;
|
|
|
|
self->y = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
void popup_size(Popup *self, int w, int h)
|
|
|
|
{
|
|
|
|
self->w = w;
|
|
|
|
self->h = h;
|
|
|
|
}
|
|
|
|
|
|
|
|
void popup_size_to_string(Popup *self, char *text)
|
|
|
|
{
|
|
|
|
int textw, texth;
|
|
|
|
int iconw;
|
|
|
|
|
|
|
|
if (!self->a_text)
|
2003-06-21 01:53:26 +00:00
|
|
|
self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label);
|
2003-05-09 19:58:08 +00:00
|
|
|
|
|
|
|
self->a_text->texture[0].data.text.string = text;
|
2003-06-21 00:42:47 +00:00
|
|
|
RrMinsize(self->a_text, &textw, &texth);
|
2003-06-21 01:53:26 +00:00
|
|
|
textw += ob_rr_theme->bevel * 2;
|
|
|
|
texth += ob_rr_theme->bevel * 2;
|
2003-05-09 19:58:08 +00:00
|
|
|
|
2003-06-21 01:53:26 +00:00
|
|
|
self->h = texth + ob_rr_theme->bevel * 2;
|
2003-05-09 19:58:08 +00:00
|
|
|
iconw = (self->hasicon ? texth : 0);
|
2003-06-21 01:53:26 +00:00
|
|
|
self->w = textw + iconw + ob_rr_theme->bevel * (self->hasicon ? 3 : 2);
|
2003-05-09 19:58:08 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 06:38:42 +00:00
|
|
|
void popup_show(Popup *self, char *text, ObClientIcon *icon)
|
2003-05-09 19:58:08 +00:00
|
|
|
{
|
|
|
|
int x, y, w, h;
|
|
|
|
int textw, texth;
|
|
|
|
int iconw;
|
|
|
|
|
|
|
|
/* create the shit if needed */
|
2003-06-29 17:18:19 +00:00
|
|
|
if (!self->a_bg)
|
2003-06-21 01:53:26 +00:00
|
|
|
self->a_bg = RrAppearanceCopy(ob_rr_theme->app_hilite_bg);
|
2003-06-29 17:18:19 +00:00
|
|
|
if (self->hasicon && !self->a_icon)
|
|
|
|
self->a_icon = RrAppearanceCopy(ob_rr_theme->app_icon);
|
2003-05-09 19:58:08 +00:00
|
|
|
if (!self->a_text)
|
2003-06-21 01:53:26 +00:00
|
|
|
self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label);
|
2003-05-09 19:58:08 +00:00
|
|
|
|
2003-06-29 17:18:19 +00:00
|
|
|
XSetWindowBorderWidth(ob_display, self->bg, ob_rr_theme->bwidth);
|
|
|
|
XSetWindowBorder(ob_display, self->bg, ob_rr_theme->b_color->pixel);
|
|
|
|
|
2003-05-09 19:58:08 +00:00
|
|
|
/* set up the textures */
|
|
|
|
self->a_text->texture[0].data.text.string = text;
|
|
|
|
if (self->hasicon) {
|
|
|
|
if (icon) {
|
2003-06-21 00:42:47 +00:00
|
|
|
self->a_icon->texture[0].type = RR_TEXTURE_RGBA;
|
2003-05-09 19:58:08 +00:00
|
|
|
self->a_icon->texture[0].data.rgba.width = icon->width;
|
|
|
|
self->a_icon->texture[0].data.rgba.height = icon->height;
|
|
|
|
self->a_icon->texture[0].data.rgba.data = icon->data;
|
|
|
|
} else
|
2003-06-21 00:42:47 +00:00
|
|
|
self->a_icon->texture[0].type = RR_TEXTURE_NONE;
|
2003-05-09 19:58:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* measure the shit out */
|
2003-06-21 00:42:47 +00:00
|
|
|
RrMinsize(self->a_text, &textw, &texth);
|
2003-06-21 01:53:26 +00:00
|
|
|
textw += ob_rr_theme->bevel * 2;
|
|
|
|
texth += ob_rr_theme->bevel * 2;
|
2003-05-09 19:58:08 +00:00
|
|
|
|
|
|
|
/* set the sizes up and reget the text sizes from the calculated
|
|
|
|
outer sizes */
|
|
|
|
if (self->h) {
|
|
|
|
h = self->h;
|
2003-06-21 01:53:26 +00:00
|
|
|
texth = h - (ob_rr_theme->bevel * 2);
|
2003-05-09 19:58:08 +00:00
|
|
|
} else
|
2003-06-21 01:53:26 +00:00
|
|
|
h = texth + ob_rr_theme->bevel * 2;
|
2003-05-09 19:58:08 +00:00
|
|
|
iconw = (self->hasicon ? texth : 0);
|
|
|
|
if (self->w) {
|
|
|
|
w = self->w;
|
2003-06-21 01:53:26 +00:00
|
|
|
textw = w - (iconw + ob_rr_theme->bevel * (self->hasicon ? 3 : 2));
|
2003-05-09 19:58:08 +00:00
|
|
|
} else
|
2003-06-21 01:53:26 +00:00
|
|
|
w = textw + iconw + ob_rr_theme->bevel * (self->hasicon ? 3 : 2);
|
2003-05-09 19:58:08 +00:00
|
|
|
/* sanity checks to avoid crashes! */
|
|
|
|
if (w < 1) w = 1;
|
|
|
|
if (h < 1) h = 1;
|
|
|
|
if (textw < 1) textw = 1;
|
|
|
|
if (texth < 1) texth = 1;
|
|
|
|
|
|
|
|
/* set up the x coord */
|
|
|
|
x = self->x;
|
|
|
|
switch (self->gravity) {
|
|
|
|
case NorthGravity:
|
|
|
|
case CenterGravity:
|
|
|
|
case SouthGravity:
|
|
|
|
x -= w / 2;
|
|
|
|
break;
|
|
|
|
case NorthEastGravity:
|
|
|
|
case EastGravity:
|
|
|
|
case SouthEastGravity:
|
|
|
|
x -= w;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set up the y coord */
|
|
|
|
y = self->y;
|
|
|
|
switch (self->gravity) {
|
|
|
|
case WestGravity:
|
|
|
|
case CenterGravity:
|
|
|
|
case EastGravity:
|
|
|
|
y -= h / 2;
|
|
|
|
break;
|
|
|
|
case SouthWestGravity:
|
|
|
|
case SouthGravity:
|
|
|
|
case SouthEastGravity:
|
|
|
|
y -= h;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set the windows/appearances up */
|
|
|
|
XMoveResizeWindow(ob_display, self->bg, x, y, w, h);
|
|
|
|
|
2003-06-20 00:05:51 +00:00
|
|
|
self->a_text->surface.parent = self->a_bg;
|
|
|
|
self->a_text->surface.parentx = iconw +
|
2003-06-21 01:53:26 +00:00
|
|
|
ob_rr_theme->bevel * (self->hasicon ? 2 : 1);
|
|
|
|
self->a_text->surface.parenty = ob_rr_theme->bevel;
|
2003-05-09 19:58:08 +00:00
|
|
|
XMoveResizeWindow(ob_display, self->text,
|
2003-06-21 01:53:26 +00:00
|
|
|
iconw + ob_rr_theme->bevel * (self->hasicon ? 2 : 1),
|
|
|
|
ob_rr_theme->bevel, textw, texth);
|
2003-05-09 19:58:08 +00:00
|
|
|
|
|
|
|
if (self->hasicon) {
|
|
|
|
if (iconw < 1) iconw = 1; /* sanity check for crashes */
|
2003-06-20 00:05:51 +00:00
|
|
|
self->a_icon->surface.parent = self->a_bg;
|
2003-06-21 01:53:26 +00:00
|
|
|
self->a_icon->surface.parentx = ob_rr_theme->bevel;
|
|
|
|
self->a_icon->surface.parenty = ob_rr_theme->bevel;
|
2003-05-09 19:58:08 +00:00
|
|
|
XMoveResizeWindow(ob_display, self->icon,
|
2003-06-21 01:53:26 +00:00
|
|
|
ob_rr_theme->bevel, ob_rr_theme->bevel,
|
|
|
|
iconw, texth);
|
2003-05-09 19:58:08 +00:00
|
|
|
}
|
|
|
|
|
2003-06-21 00:42:47 +00:00
|
|
|
RrPaint(self->a_bg, self->bg, w, h);
|
|
|
|
RrPaint(self->a_text, self->text, textw, texth);
|
2003-05-09 19:58:08 +00:00
|
|
|
if (self->hasicon)
|
2003-06-21 00:42:47 +00:00
|
|
|
RrPaint(self->a_icon, self->icon, iconw, texth);
|
2003-05-09 19:58:08 +00:00
|
|
|
|
2003-05-11 23:31:43 +00:00
|
|
|
if (!self->mapped) {
|
|
|
|
XMapWindow(ob_display, self->bg);
|
|
|
|
stacking_raise(INTERNAL_AS_WINDOW(self));
|
|
|
|
self->mapped = TRUE;
|
|
|
|
}
|
2003-05-09 19:58:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void popup_hide(Popup *self)
|
|
|
|
{
|
2003-05-11 23:31:43 +00:00
|
|
|
if (self->mapped) {
|
|
|
|
XUnmapWindow(ob_display, self->bg);
|
|
|
|
self->mapped = FALSE;
|
|
|
|
}
|
2003-05-09 19:58:08 +00:00
|
|
|
}
|