new popups with subclasses, added an ObIconPopup for popups with icons, and ObPagerPopup, for a popup with a pager on it.

better logic also for the desktop layout code figuring out how many rows and columns there are.
This commit is contained in:
Dana Jansens 2003-09-12 06:00:17 +00:00
parent 5d658c98e2
commit 4be58bf137
6 changed files with 400 additions and 138 deletions

View file

@ -22,11 +22,11 @@ GList **focus_order; /* these lists are created when screen_startup
sets the number of desktops */ sets the number of desktops */
ObClient *focus_cycle_target; ObClient *focus_cycle_target;
static Popup *focus_cycle_popup; static ObIconPopup *focus_cycle_popup;
void focus_startup(gboolean reconfig) void focus_startup(gboolean reconfig)
{ {
focus_cycle_popup = popup_new(TRUE); focus_cycle_popup = icon_popup_new(TRUE);
if (!reconfig) if (!reconfig)
/* start with nothing focused */ /* start with nothing focused */
@ -37,7 +37,7 @@ void focus_shutdown(gboolean reconfig)
{ {
guint i; guint i;
popup_free(focus_cycle_popup); icon_popup_free(focus_cycle_popup);
if (!reconfig) { if (!reconfig) {
for (i = 0; i < screen_num_desktops; ++i) for (i = 0; i < screen_num_desktops; ++i)
@ -223,22 +223,22 @@ void focus_fallback(ObFocusFallbackType type)
static void popup_cycle(ObClient *c, gboolean show) static void popup_cycle(ObClient *c, gboolean show)
{ {
if (!show) { if (!show) {
popup_hide(focus_cycle_popup); icon_popup_hide(focus_cycle_popup);
} else { } else {
Rect *a; Rect *a;
ObClient *p = c; ObClient *p = c;
char *title; char *title;
a = screen_physical_area_monitor(0); a = screen_physical_area_monitor(0);
popup_position(focus_cycle_popup, CenterGravity, icon_popup_position(focus_cycle_popup, CenterGravity,
a->x + a->width / 2, a->y + a->height / 2); a->x + a->width / 2, a->y + a->height / 2);
/* popup_size(focus_cycle_popup, a->height/2, a->height/16); /* icon_popup_size(focus_cycle_popup, a->height/2, a->height/16);
popup_show(focus_cycle_popup, c->title, icon_popup_show(focus_cycle_popup, c->title,
client_icon(c, a->height/16, a->height/16)); client_icon(c, a->height/16, a->height/16));
*/ */
/* XXX the size and the font extents need to be related on some level /* XXX the size and the font extents need to be related on some level
*/ */
popup_size(focus_cycle_popup, POPUP_WIDTH, POPUP_HEIGHT); icon_popup_size(focus_cycle_popup, POPUP_WIDTH, POPUP_HEIGHT);
/* use the transient's parent's title/icon */ /* use the transient's parent's title/icon */
while (p->transient_for && p->transient_for != OB_TRAN_GROUP) while (p->transient_for && p->transient_for != OB_TRAN_GROUP)
@ -252,9 +252,10 @@ static void popup_cycle(ObClient *c, gboolean show)
(p->iconic ? p->icon_title : p->title), (p->iconic ? p->icon_title : p->title),
NULL); NULL);
popup_show(focus_cycle_popup, icon_popup_show(focus_cycle_popup,
(title ? title : (c->iconic ? c->icon_title : c->title)), (title ? title :
client_icon(p, 48, 48)); (c->iconic ? c->icon_title : c->title)),
client_icon(p, 48, 48));
g_free(title); g_free(title);
} }
} }

View file

@ -26,7 +26,7 @@ static guint button;
static guint32 corner; static guint32 corner;
static ObCorner lockcorner; static ObCorner lockcorner;
static Popup *popup = NULL; static ObPopup *popup = NULL;
static void client_dest(gpointer client) static void client_dest(gpointer client)
{ {
@ -61,7 +61,7 @@ static void popup_coords(ObClient *c, char *format, int a, int b)
c->area.width / 2, c->area.width / 2,
c->frame->area.y + c->frame->size.top + c->frame->area.y + c->frame->size.top +
c->area.height / 2); c->area.height / 2);
popup_show(popup, text, NULL); popup_show(popup, text);
g_free(text); g_free(text);
} }

View file

@ -189,14 +189,6 @@ int main(int argc, char **argv)
if (screen_annex()) { /* it will be ours! */ if (screen_annex()) { /* it will be ours! */
do { do {
event_startup(reconfigure);
grab_startup(reconfigure);
/* focus_backup is used for stacking, so this needs to come before
anything that calls stacking_add */
focus_startup(reconfigure);
window_startup(reconfigure);
sn_startup(reconfigure);
{ {
ObParseInst *i; ObParseInst *i;
xmlDocPtr doc; xmlDocPtr doc;
@ -218,12 +210,21 @@ int main(int argc, char **argv)
/* load the theme specified in the rc file */ /* load the theme specified in the rc file */
{ {
RrTheme *theme; RrTheme *theme;
if ((theme = RrThemeNew(ob_rr_inst, config_theme))) if ((theme = RrThemeNew(ob_rr_inst, config_theme))) {
RrThemeFree(ob_rr_theme);
ob_rr_theme = theme; ob_rr_theme = theme;
}
if (ob_rr_theme == NULL) if (ob_rr_theme == NULL)
ob_exit_with_error("Unable to load a theme."); ob_exit_with_error("Unable to load a theme.");
} }
event_startup(reconfigure);
grab_startup(reconfigure);
/* focus_backup is used for stacking, so this needs to come before
anything that calls stacking_add */
focus_startup(reconfigure);
window_startup(reconfigure);
sn_startup(reconfigure);
moveresize_startup(reconfigure); moveresize_startup(reconfigure);
screen_startup(reconfigure); screen_startup(reconfigure);
group_startup(reconfigure); group_startup(reconfigure);

View file

@ -3,43 +3,22 @@
#include "openbox.h" #include "openbox.h"
#include "frame.h" #include "frame.h"
#include "client.h" #include "client.h"
#include "window.h"
#include "stacking.h" #include "stacking.h"
#include "screen.h"
#include "render/render.h" #include "render/render.h"
#include "render/theme.h" #include "render/theme.h"
struct _ObPopup ObPopup *popup_new(gboolean hasicon)
{
ObWindow obwin;
Window bg;
Window icon;
Window text;
gboolean hasicon;
RrAppearance *a_bg;
RrAppearance *a_icon;
RrAppearance *a_text;
gint gravity;
gint x;
gint y;
gint w;
gint h;
gboolean mapped;
};
Popup *popup_new(gboolean hasicon)
{ {
XSetWindowAttributes attrib; XSetWindowAttributes attrib;
Popup *self = g_new(Popup, 1); ObPopup *self = g_new0(ObPopup, 1);
self->obwin.type = Window_Internal; self->obwin.type = Window_Internal;
self->hasicon = hasicon; self->hasicon = hasicon;
self->a_text = NULL;
self->gravity = NorthWestGravity; self->gravity = NorthWestGravity;
self->x = self->y = self->w = self->h = 0; self->x = self->y = self->w = self->h = 0;
self->mapped = FALSE; self->a_bg = RrAppearanceCopy(ob_rr_theme->app_hilite_bg);
self->a_bg = self->a_icon = self->a_text = NULL; self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label);
attrib.override_redirect = True; attrib.override_redirect = True;
self->bg = XCreateWindow(ob_display, RootWindow(ob_display, ob_screen), self->bg = XCreateWindow(ob_display, RootWindow(ob_display, ob_screen),
@ -51,54 +30,42 @@ Popup *popup_new(gboolean hasicon)
0, 0, 1, 1, 0, RrDepth(ob_rr_inst), 0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
InputOutput, RrVisual(ob_rr_inst), 0, NULL); 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->text);
XMapWindow(ob_display, self->icon);
stacking_add(INTERNAL_AS_WINDOW(self)); stacking_add(INTERNAL_AS_WINDOW(self));
return self; return self;
} }
void popup_free(Popup *self) void popup_free(ObPopup *self)
{ {
if (self) { if (self) {
XDestroyWindow(ob_display, self->bg); XDestroyWindow(ob_display, self->bg);
XDestroyWindow(ob_display, self->text); XDestroyWindow(ob_display, self->text);
XDestroyWindow(ob_display, self->icon);
RrAppearanceFree(self->a_bg); RrAppearanceFree(self->a_bg);
RrAppearanceFree(self->a_icon);
RrAppearanceFree(self->a_text); RrAppearanceFree(self->a_text);
stacking_remove(self); stacking_remove(self);
g_free(self); g_free(self);
} }
} }
void popup_position(Popup *self, gint gravity, gint x, gint y) void popup_position(ObPopup *self, gint gravity, gint x, gint y)
{ {
self->gravity = gravity; self->gravity = gravity;
self->x = x; self->x = x;
self->y = y; self->y = y;
} }
void popup_size(Popup *self, gint w, gint h) void popup_size(ObPopup *self, gint w, gint h)
{ {
self->w = w; self->w = w;
self->h = h; self->h = h;
} }
void popup_size_to_string(Popup *self, gchar *text) void popup_size_to_string(ObPopup *self, gchar *text)
{ {
gint textw, texth; gint textw, texth;
gint iconw; gint iconw;
if (!self->a_text)
self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label);
self->a_text->texture[0].data.text.string = text; self->a_text->texture[0].data.text.string = text;
RrMinsize(self->a_text, &textw, &texth); RrMinsize(self->a_text, &textw, &texth);
/*XXX textw += ob_rr_theme->bevel * 2;*/ /*XXX textw += ob_rr_theme->bevel * 2;*/
@ -109,29 +76,18 @@ void popup_size_to_string(Popup *self, gchar *text)
self->w = textw + iconw + ob_rr_theme->padding * (self->hasicon ? 3 : 2); self->w = textw + iconw + ob_rr_theme->padding * (self->hasicon ? 3 : 2);
} }
void popup_set_text_align(Popup *self, RrJustify align) void popup_set_text_align(ObPopup *self, RrJustify align)
{ {
if (!self->a_text)
self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label);
self->a_text->texture[0].data.text.justify = align; self->a_text->texture[0].data.text.justify = align;
} }
void popup_show(Popup *self, gchar *text, ObClientIcon *icon) void popup_show(ObPopup *self, gchar *text)
{ {
gint l, t, r, b; gint l, t, r, b;
gint x, y, w, h; gint x, y, w, h;
gint textw, texth; gint textw, texth;
gint iconw; gint iconw;
/* create the shit if needed */
if (!self->a_bg)
self->a_bg = RrAppearanceCopy(ob_rr_theme->app_hilite_bg);
if (self->hasicon && !self->a_icon)
self->a_icon = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
if (!self->a_text)
self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label);
RrMargins(self->a_bg, &l, &t, &r, &b); RrMargins(self->a_bg, &l, &t, &r, &b);
XSetWindowBorderWidth(ob_display, self->bg, ob_rr_theme->bwidth); XSetWindowBorderWidth(ob_display, self->bg, ob_rr_theme->bwidth);
@ -139,15 +95,6 @@ void popup_show(Popup *self, gchar *text, ObClientIcon *icon)
/* set up the textures */ /* set up the textures */
self->a_text->texture[0].data.text.string = text; self->a_text->texture[0].data.text.string = text;
if (self->hasicon) {
if (icon) {
self->a_icon->texture[0].type = RR_TEXTURE_RGBA;
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
self->a_icon->texture[0].type = RR_TEXTURE_NONE;
}
/* measure the shit out */ /* measure the shit out */
RrMinsize(self->a_text, &textw, &texth); RrMinsize(self->a_text, &textw, &texth);
@ -213,23 +160,19 @@ void popup_show(Popup *self, gchar *text, ObClientIcon *icon)
ob_rr_theme->padding * (self->hasicon ? 2 : 1); ob_rr_theme->padding * (self->hasicon ? 2 : 1);
self->a_text->surface.parenty = t + ob_rr_theme->padding; self->a_text->surface.parenty = t + ob_rr_theme->padding;
XMoveResizeWindow(ob_display, self->text, XMoveResizeWindow(ob_display, self->text,
l + iconw + ob_rr_theme->padding * (self->hasicon ? 2 : 1), l + iconw + ob_rr_theme->padding *
(self->hasicon ? 2 : 1),
t + ob_rr_theme->padding, textw, texth); t + ob_rr_theme->padding, textw, texth);
if (self->hasicon) {
if (iconw < 1) iconw = 1; /* sanity check for crashes */
self->a_icon->surface.parent = self->a_bg;
self->a_icon->surface.parentx = l + ob_rr_theme->padding;
self->a_icon->surface.parenty = t + ob_rr_theme->padding;
XMoveResizeWindow(ob_display, self->icon,
l + ob_rr_theme->padding, t + ob_rr_theme->padding,
iconw, texth);
}
RrPaint(self->a_bg, self->bg, w, h); RrPaint(self->a_bg, self->bg, w, h);
RrPaint(self->a_text, self->text, textw, texth); RrPaint(self->a_text, self->text, textw, texth);
if (self->hasicon)
RrPaint(self->a_icon, self->icon, iconw, texth); if (self->hasicon) {
if (iconw < 1) iconw = 1; /* sanity check for crashes */
if (self->draw_icon)
self->draw_icon(l + ob_rr_theme->padding, t + ob_rr_theme->padding,
iconw, texth, self->draw_icon_data);
}
if (!self->mapped) { if (!self->mapped) {
XMapWindow(ob_display, self->bg); XMapWindow(ob_display, self->bg);
@ -238,10 +181,253 @@ void popup_show(Popup *self, gchar *text, ObClientIcon *icon)
} }
} }
void popup_hide(Popup *self) void popup_hide(ObPopup *self)
{ {
if (self->mapped) { if (self->mapped) {
XUnmapWindow(ob_display, self->bg); XUnmapWindow(ob_display, self->bg);
self->mapped = FALSE; self->mapped = FALSE;
} }
} }
static void icon_popup_draw_icon(gint x, gint y, gint w, gint h, gpointer data)
{
ObIconPopup *self = data;
self->a_icon->surface.parent = self->popup->a_bg;
self->a_icon->surface.parentx = x;
self->a_icon->surface.parenty = y;
XMoveResizeWindow(ob_display, self->icon, x, y, w, h);
RrPaint(self->a_icon, self->icon, w, h);
}
ObIconPopup *icon_popup_new()
{
ObIconPopup *self;
self = g_new0(ObIconPopup, 1);
self->popup = popup_new(TRUE);
self->a_icon = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
self->icon = XCreateWindow(ob_display, self->popup->bg,
0, 0, 1, 1, 0,
RrDepth(ob_rr_inst), InputOutput,
RrVisual(ob_rr_inst), 0, NULL);
XMapWindow(ob_display, self->icon);
self->popup->draw_icon = icon_popup_draw_icon;
self->popup->draw_icon_data = self;
return self;
}
void icon_popup_free(ObIconPopup *self)
{
if (self) {
XDestroyWindow(ob_display, self->icon);
RrAppearanceFree(self->a_icon);
popup_free(self->popup);
g_free(self);
}
}
void icon_popup_show(ObIconPopup *self,
gchar *text, struct _ObClientIcon *icon)
{
if (icon) {
self->a_icon->texture[0].type = RR_TEXTURE_RGBA;
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
self->a_icon->texture[0].type = RR_TEXTURE_NONE;
popup_show(self->popup, text);
}
static void pager_popup_draw_icon(gint px, gint py, gint w, gint h,
gpointer data)
{
ObPagerPopup *self = data;
gint x, y;
guint i;
guint rown, n;
guint horz_inc;
guint vert_inc;
guint r, c;
gint eachw, eachh;
eachw = (w - ob_rr_theme->bwidth -
(screen_desktop_layout.columns * ob_rr_theme->bwidth))
/ screen_desktop_layout.columns;
eachh = (h - ob_rr_theme->bwidth -
(screen_desktop_layout.rows * ob_rr_theme->bwidth))
/ screen_desktop_layout.rows;
/* make them squares */
eachw = eachh = MIN(eachw, eachh);
g_message("dif %d %d %d %d ",
(screen_desktop_layout.columns * (eachw + ob_rr_theme->bwidth) +
ob_rr_theme->bwidth), w,
(screen_desktop_layout.rows * (eachh + ob_rr_theme->bwidth) +
ob_rr_theme->bwidth), h);
/* center */
px += (w - (screen_desktop_layout.columns * (eachw + ob_rr_theme->bwidth) +
ob_rr_theme->bwidth)) / 2;
py += (h - (screen_desktop_layout.rows * (eachh + ob_rr_theme->bwidth) +
ob_rr_theme->bwidth)) / 2;
g_message("%d %d %d %d", px, py, eachw, eachh);
if (eachw <= 0 || eachh <= 0)
return;
switch (screen_desktop_layout.start_corner) {
case OB_CORNER_TOPLEFT:
n = 0;
switch (screen_desktop_layout.orientation) {
case OB_ORIENTATION_HORZ:
horz_inc = 1;
vert_inc = screen_desktop_layout.columns;
break;
case OB_ORIENTATION_VERT:
horz_inc = screen_desktop_layout.rows;
vert_inc = 1;
break;
}
break;
case OB_CORNER_TOPRIGHT:
n = screen_desktop_layout.columns;
switch (screen_desktop_layout.orientation) {
case OB_ORIENTATION_HORZ:
horz_inc = -1;
vert_inc = screen_desktop_layout.columns;
break;
case OB_ORIENTATION_VERT:
horz_inc = -screen_desktop_layout.rows;
vert_inc = 1;
break;
}
break;
case OB_CORNER_BOTTOMLEFT:
n = screen_desktop_layout.rows;
switch (screen_desktop_layout.orientation) {
case OB_ORIENTATION_HORZ:
horz_inc = 1;
vert_inc = -screen_desktop_layout.columns;
break;
case OB_ORIENTATION_VERT:
horz_inc = screen_desktop_layout.rows;
vert_inc = -1;
break;
}
break;
case OB_CORNER_BOTTOMRIGHT:
n = MAX(self->desks,
screen_desktop_layout.rows * screen_desktop_layout.columns);
switch (screen_desktop_layout.orientation) {
case OB_ORIENTATION_HORZ:
horz_inc = -1;
vert_inc = -screen_desktop_layout.columns;
break;
case OB_ORIENTATION_VERT:
horz_inc = -screen_desktop_layout.rows;
vert_inc = -1;
break;
}
break;
}
g_message("%d %d %d", n, horz_inc, vert_inc);
rown = n;
i = 0;
for (r = 0, y = 0; r < screen_desktop_layout.rows;
++r, y += eachh + ob_rr_theme->bwidth)
{
for (c = 0, x = 0; c < screen_desktop_layout.columns;
++c, x += eachw + ob_rr_theme->bwidth)
{
RrAppearance *a;
g_message("i %d n %d", i, n);
if (i >= self->desks)
break;
a = (n == self->curdesk ? self->hilight : self->unhilight);
a->surface.parent = self->popup->a_bg;
a->surface.parentx = x + px;
a->surface.parenty = y + py;
XMoveResizeWindow(ob_display, self->wins[i],
x + px, y + py, eachw, eachh);
RrPaint(a, self->wins[i], eachw, eachh);
n += horz_inc;
++i;
}
n = rown += vert_inc;
}
}
ObPagerPopup *pager_popup_new()
{
ObPagerPopup *self;
self = g_new(ObPagerPopup, 1);
self->popup = popup_new(TRUE);
self->desks = 0;
self->wins = g_new(Window, self->desks);
self->hilight = RrAppearanceCopy(ob_rr_theme->app_hilite_fg);
self->unhilight = RrAppearanceCopy(ob_rr_theme->app_unhilite_fg);
self->popup->draw_icon = pager_popup_draw_icon;
self->popup->draw_icon_data = self;
return self;
}
void pager_popup_free(ObPagerPopup *self)
{
if (self) {
guint i;
for (i = 0; i < self->desks; ++i)
XDestroyWindow(ob_display, self->wins[i]);
RrAppearanceFree(self->hilight);
RrAppearanceFree(self->unhilight);
popup_free(self->popup);
g_free(self);
}
}
void pager_popup_show(ObPagerPopup *self, gchar *text, guint desk)
{
guint i;
if (screen_num_desktops < self->desks)
for (i = screen_num_desktops; i < self->desks; ++i)
XDestroyWindow(ob_display, self->wins[i]);
if (screen_num_desktops != self->desks)
self->wins = g_renew(Window, self->wins, screen_num_desktops);
if (screen_num_desktops > self->desks)
for (i = self->desks; i < screen_num_desktops; ++i) {
XSetWindowAttributes attr;
attr.border_pixel = RrColorPixel(ob_rr_theme->b_color);
self->wins[i] = XCreateWindow(ob_display, self->popup->bg,
0, 0, 1, 1, ob_rr_theme->bwidth,
RrDepth(ob_rr_inst), InputOutput,
RrVisual(ob_rr_inst), CWBorderPixel,
&attr);
XMapWindow(ob_display, self->wins[i]);
}
self->desks = screen_num_desktops;
self->curdesk = desk;
popup_show(self->popup, text);
}

View file

@ -1,33 +1,100 @@
#ifndef __popup_h #ifndef __popup_h
#define __popup_h #define __popup_h
#include <glib.h> #include "window.h"
#include "render/render.h" #include "render/render.h"
#include <glib.h>
struct _ObClientIcon; struct _ObClientIcon;
#define POPUP_WIDTH 320 #define POPUP_WIDTH 320
#define POPUP_HEIGHT 48 #define POPUP_HEIGHT 48
typedef struct _ObPopup Popup; typedef struct _ObPopup ObPopup;
typedef struct _ObIconPopup ObIconPopup;
typedef struct _ObPagerPopup ObPagerPopup;
Popup *popup_new(gboolean hasicon); struct _ObPopup
void popup_free(Popup *self); {
ObWindow obwin;
Window bg;
Window text;
gboolean hasicon;
RrAppearance *a_bg;
RrAppearance *a_text;
gint gravity;
gint x;
gint y;
gint w;
gint h;
gboolean mapped;
void (*draw_icon)(gint x, gint y, gint w, gint h, gpointer data);
gpointer draw_icon_data;
};
struct _ObIconPopup
{
ObPopup *popup;
Window icon;
RrAppearance *a_icon;
};
struct _ObPagerPopup
{
ObPopup *popup;
guint desks;
guint curdesk;
Window *wins;
RrAppearance *hilight;
RrAppearance *unhilight;
};
ObPopup *popup_new(gboolean hasicon);
void popup_free(ObPopup *self);
/*! Position the popup. The gravity rules are not the same X uses for windows, /*! Position the popup. The gravity rules are not the same X uses for windows,
instead of the position being the top-left of the window, the gravity instead of the position being the top-left of the window, the gravity
specifies which corner of the popup will be placed at the given coords. specifies which corner of the popup will be placed at the given coords.
Static and Forget gravity are equivilent to NorthWest. Static and Forget gravity are equivilent to NorthWest.
*/ */
void popup_position(Popup *self, gint gravity, gint x, gint y); void popup_position(ObPopup *self, gint gravity, gint x, gint y);
/*! Set the sizes for the popup. When set to 0, the size will be based on /*! Set the sizes for the popup. When set to 0, the size will be based on
the text size. */ the text size. */
void popup_size(Popup *self, gint w, gint h); void popup_size(ObPopup *self, gint w, gint h);
void popup_size_to_string(Popup *self, gchar *text); void popup_size_to_string(ObPopup *self, gchar *text);
void popup_set_text_align(Popup *self, RrJustify align); void popup_set_text_align(ObPopup *self, RrJustify align);
void popup_show(Popup *self, gchar *text, struct _ObClientIcon *icon); void popup_show(ObPopup *self, gchar *text);
void popup_hide(Popup *self); void popup_hide(ObPopup *self);
RrAppearance *popup_icon_appearance(ObPopup *self);
ObIconPopup *icon_popup_new();
void icon_popup_free(ObIconPopup *self);
void icon_popup_show(ObIconPopup *self,
gchar *text, struct _ObClientIcon *icon);
#define icon_popup_hide(p) popup_hide((p)->popup)
#define icon_popup_position(p, g, x, y) popup_position((p)->popup,(g),(x),(y))
#define icon_popup_size(p, w, h) popup_size((p)->popup,(w),(h))
#define icon_popup_size_to_string(p, s) popup_size_to_string((p)->popup,(s))
#define icon_popup_set_text_align(p, j) popup_set_text_align((p)->popup,(j))
ObPagerPopup *pager_popup_new();
void pager_popup_free(ObPagerPopup *self);
void pager_popup_show(ObPagerPopup *self, gchar *text, guint desk);
#define pager_popup_hide(p) popup_hide((p)->popup)
#define pager_popup_position(p, g, x, y) popup_position((p)->popup,(g),(x),(y))
#define pager_popup_size(p, w, h) popup_size((p)->popup,(w),(h))
#define pager_popup_size_to_string(p, s) popup_size_to_string((p)->popup,(s))
#define pager_popup_set_text_align(p, j) popup_set_text_align((p)->popup,(j))
#endif #endif

View file

@ -41,7 +41,7 @@ Window screen_support_win;
static Rect **area; /* array of desktop holding array of xinerama areas */ static Rect **area; /* array of desktop holding array of xinerama areas */
static Rect *monitor_area; static Rect *monitor_area;
static Popup *desktop_cycle_popup; static ObPagerPopup *desktop_cycle_popup;
static gboolean replace_wm() static gboolean replace_wm()
{ {
@ -252,7 +252,7 @@ void screen_startup(gboolean reconfig)
GSList *it; GSList *it;
guint i; guint i;
desktop_cycle_popup = popup_new(FALSE); desktop_cycle_popup = pager_popup_new(FALSE);
if (!reconfig) if (!reconfig)
/* get the initial size */ /* get the initial size */
@ -288,7 +288,7 @@ void screen_shutdown(gboolean reconfig)
{ {
Rect **r; Rect **r;
popup_free(desktop_cycle_popup); pager_popup_free(desktop_cycle_popup);
if (!reconfig) { if (!reconfig) {
XSelectInput(ob_display, RootWindow(ob_display, ob_screen), XSelectInput(ob_display, RootWindow(ob_display, ob_screen),
@ -560,19 +560,18 @@ static void popup_cycle(guint d, gboolean show)
Rect *a; Rect *a;
if (!show) { if (!show) {
popup_hide(desktop_cycle_popup); pager_popup_hide(desktop_cycle_popup);
} else { } else {
a = screen_physical_area_monitor(0); a = screen_physical_area_monitor(0);
popup_position(desktop_cycle_popup, CenterGravity, pager_popup_position(desktop_cycle_popup, CenterGravity,
a->x + a->width / 2, a->y + a->height / 2); a->x + a->width / 2, a->y + a->height / 2);
/* XXX the size and the font extents need to be related on some level /* XXX the size and the font extents need to be related on some level
*/ */
popup_size(desktop_cycle_popup, POPUP_WIDTH, POPUP_HEIGHT); pager_popup_size(desktop_cycle_popup, POPUP_WIDTH, POPUP_HEIGHT);
popup_set_text_align(desktop_cycle_popup, RR_JUSTIFY_CENTER); pager_popup_set_text_align(desktop_cycle_popup, RR_JUSTIFY_CENTER);
popup_show(desktop_cycle_popup, pager_popup_show(desktop_cycle_popup, screen_desktop_names[d], d);
screen_desktop_names[d], NULL);
} }
} }
@ -723,31 +722,39 @@ void screen_update_layout()
goto screen_update_layout_bail; goto screen_update_layout_bail;
} }
cols = data[1];
rows = data[2];
/* fill in a zero rows/columns */ /* fill in a zero rows/columns */
if ((data[1] == 0 && data[2] == 0) || /* both 0's is bad data.. */ if ((cols == 0 && rows == 0)) { /* both 0's is bad data.. */
(data[1] != 0 && data[2] != 0)) { /* no 0's is bad data.. */
goto screen_update_layout_bail; goto screen_update_layout_bail;
} else { } else {
if (data[1] == 0) { if (cols == 0) {
data[1] = (screen_num_desktops + cols = screen_num_desktops / rows;
screen_num_desktops % data[2]) / data[2]; if (rows * cols < screen_num_desktops)
} else if (data[2] == 0) { cols++;
data[2] = (screen_num_desktops + if (rows * cols >= screen_num_desktops + cols)
screen_num_desktops % data[1]) / data[1]; rows--;
} else if (rows == 0) {
rows = screen_num_desktops / rows;
if (cols * rows < screen_num_desktops)
rows++;
if (cols * rows >= screen_num_desktops + rows)
cols--;
} }
cols = data[1];
rows = data[2];
} }
/* bounds checking */ /* bounds checking */
if (orient == OB_ORIENTATION_HORZ) { if (orient == OB_ORIENTATION_HORZ) {
rows = MIN(rows, screen_num_desktops); cols = MIN(screen_num_desktops, cols);
cols = MIN(cols, ((screen_num_desktops + rows = MIN(rows, (screen_num_desktops + cols - 1) / cols);
(screen_num_desktops % rows)) / rows)); cols = screen_num_desktops / rows +
!!(screen_num_desktops % rows);
} else { } else {
cols = MIN(cols, screen_num_desktops); rows = MIN(screen_num_desktops, rows);
rows = MIN(rows, ((screen_num_desktops + cols = MIN(cols, (screen_num_desktops + rows - 1) / rows);
(screen_num_desktops % cols)) / cols)); rows = screen_num_desktops / cols +
!!(screen_num_desktops % cols);
} }
valid = TRUE; valid = TRUE;