From 4be58bf13719fd22cb08a7f016eaf757640ccd05 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 12 Sep 2003 06:00:17 +0000 Subject: [PATCH] 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. --- openbox/focus.c | 27 ++-- openbox/moveresize.c | 4 +- openbox/openbox.c | 19 +-- openbox/popup.c | 340 +++++++++++++++++++++++++++++++++---------- openbox/popup.h | 87 +++++++++-- openbox/screen.c | 59 ++++---- 6 files changed, 399 insertions(+), 137 deletions(-) diff --git a/openbox/focus.c b/openbox/focus.c index 6ba125ef..9c29345f 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -22,11 +22,11 @@ GList **focus_order; /* these lists are created when screen_startup sets the number of desktops */ ObClient *focus_cycle_target; -static Popup *focus_cycle_popup; +static ObIconPopup *focus_cycle_popup; void focus_startup(gboolean reconfig) { - focus_cycle_popup = popup_new(TRUE); + focus_cycle_popup = icon_popup_new(TRUE); if (!reconfig) /* start with nothing focused */ @@ -37,7 +37,7 @@ void focus_shutdown(gboolean reconfig) { guint i; - popup_free(focus_cycle_popup); + icon_popup_free(focus_cycle_popup); if (!reconfig) { 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) { if (!show) { - popup_hide(focus_cycle_popup); + icon_popup_hide(focus_cycle_popup); } else { Rect *a; ObClient *p = c; char *title; a = screen_physical_area_monitor(0); - popup_position(focus_cycle_popup, CenterGravity, - a->x + a->width / 2, a->y + a->height / 2); -/* popup_size(focus_cycle_popup, a->height/2, a->height/16); - popup_show(focus_cycle_popup, c->title, - client_icon(c, a->height/16, a->height/16)); + icon_popup_position(focus_cycle_popup, CenterGravity, + a->x + a->width / 2, a->y + a->height / 2); +/* icon_popup_size(focus_cycle_popup, a->height/2, a->height/16); + icon_popup_show(focus_cycle_popup, c->title, + client_icon(c, a->height/16, a->height/16)); */ /* 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 */ 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), NULL); - popup_show(focus_cycle_popup, - (title ? title : (c->iconic ? c->icon_title : c->title)), - client_icon(p, 48, 48)); + icon_popup_show(focus_cycle_popup, + (title ? title : + (c->iconic ? c->icon_title : c->title)), + client_icon(p, 48, 48)); g_free(title); } } diff --git a/openbox/moveresize.c b/openbox/moveresize.c index 1c31a253..8df3a080 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -26,7 +26,7 @@ static guint button; static guint32 corner; static ObCorner lockcorner; -static Popup *popup = NULL; +static ObPopup *popup = NULL; 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->frame->area.y + c->frame->size.top + c->area.height / 2); - popup_show(popup, text, NULL); + popup_show(popup, text); g_free(text); } diff --git a/openbox/openbox.c b/openbox/openbox.c index d8eae91a..feeb19d9 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -189,14 +189,6 @@ int main(int argc, char **argv) if (screen_annex()) { /* it will be ours! */ 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; xmlDocPtr doc; @@ -218,12 +210,21 @@ int main(int argc, char **argv) /* load the theme specified in the rc file */ { 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; + } if (ob_rr_theme == NULL) 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); screen_startup(reconfigure); group_startup(reconfigure); diff --git a/openbox/popup.c b/openbox/popup.c index e7d455a0..592c5ee0 100644 --- a/openbox/popup.c +++ b/openbox/popup.c @@ -3,43 +3,22 @@ #include "openbox.h" #include "frame.h" #include "client.h" -#include "window.h" #include "stacking.h" +#include "screen.h" #include "render/render.h" #include "render/theme.h" -struct _ObPopup -{ - 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) +ObPopup *popup_new(gboolean hasicon) { XSetWindowAttributes attrib; - Popup *self = g_new(Popup, 1); + ObPopup *self = g_new0(ObPopup, 1); self->obwin.type = Window_Internal; self->hasicon = hasicon; - self->a_text = NULL; self->gravity = NorthWestGravity; self->x = self->y = self->w = self->h = 0; - self->mapped = FALSE; - self->a_bg = self->a_icon = self->a_text = NULL; + self->a_bg = RrAppearanceCopy(ob_rr_theme->app_hilite_bg); + self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label); attrib.override_redirect = True; 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), 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); stacking_add(INTERNAL_AS_WINDOW(self)); return self; } -void popup_free(Popup *self) +void popup_free(ObPopup *self) { if (self) { XDestroyWindow(ob_display, self->bg); XDestroyWindow(ob_display, self->text); - XDestroyWindow(ob_display, self->icon); RrAppearanceFree(self->a_bg); - RrAppearanceFree(self->a_icon); RrAppearanceFree(self->a_text); stacking_remove(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->x = x; 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->h = h; } -void popup_size_to_string(Popup *self, gchar *text) +void popup_size_to_string(ObPopup *self, gchar *text) { gint textw, texth; 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; RrMinsize(self->a_text, &textw, &texth); /*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); } -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; } -void popup_show(Popup *self, gchar *text, ObClientIcon *icon) +void popup_show(ObPopup *self, gchar *text) { gint l, t, r, b; gint x, y, w, h; gint textw, texth; 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); 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 */ 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 */ RrMinsize(self->a_text, &textw, &texth); @@ -213,24 +160,20 @@ void popup_show(Popup *self, gchar *text, ObClientIcon *icon) ob_rr_theme->padding * (self->hasicon ? 2 : 1); self->a_text->surface.parenty = t + ob_rr_theme->padding; 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); + RrPaint(self->a_bg, self->bg, w, h); + RrPaint(self->a_text, self->text, 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); + if (self->draw_icon) + self->draw_icon(l + ob_rr_theme->padding, t + ob_rr_theme->padding, + iconw, texth, self->draw_icon_data); } - RrPaint(self->a_bg, self->bg, w, h); - RrPaint(self->a_text, self->text, textw, texth); - if (self->hasicon) - RrPaint(self->a_icon, self->icon, iconw, texth); - if (!self->mapped) { XMapWindow(ob_display, self->bg); stacking_raise(INTERNAL_AS_WINDOW(self)); @@ -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) { XUnmapWindow(ob_display, self->bg); 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); +} diff --git a/openbox/popup.h b/openbox/popup.h index e06217ea..31bca5b6 100644 --- a/openbox/popup.h +++ b/openbox/popup.h @@ -1,33 +1,100 @@ #ifndef __popup_h #define __popup_h -#include +#include "window.h" #include "render/render.h" +#include struct _ObClientIcon; #define POPUP_WIDTH 320 #define POPUP_HEIGHT 48 -typedef struct _ObPopup Popup; +typedef struct _ObPopup ObPopup; +typedef struct _ObIconPopup ObIconPopup; +typedef struct _ObPagerPopup ObPagerPopup; + +struct _ObPopup +{ + 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; -Popup *popup_new(gboolean hasicon); -void popup_free(Popup *self); + 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, 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. 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 the text size. */ -void popup_size(Popup *self, gint w, gint h); -void popup_size_to_string(Popup *self, gchar *text); +void popup_size(ObPopup *self, gint w, gint h); +void popup_size_to_string(ObPopup *self, gchar *text); + +void popup_set_text_align(ObPopup *self, RrJustify align); + +void popup_show(ObPopup *self, gchar *text); +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)) -void popup_set_text_align(Popup *self, RrJustify align); +ObPagerPopup *pager_popup_new(); +void pager_popup_free(ObPagerPopup *self); -void popup_show(Popup *self, gchar *text, struct _ObClientIcon *icon); -void popup_hide(Popup *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 diff --git a/openbox/screen.c b/openbox/screen.c index f109bab2..b1b1a561 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -41,7 +41,7 @@ Window screen_support_win; static Rect **area; /* array of desktop holding array of xinerama areas */ static Rect *monitor_area; -static Popup *desktop_cycle_popup; +static ObPagerPopup *desktop_cycle_popup; static gboolean replace_wm() { @@ -252,7 +252,7 @@ void screen_startup(gboolean reconfig) GSList *it; guint i; - desktop_cycle_popup = popup_new(FALSE); + desktop_cycle_popup = pager_popup_new(FALSE); if (!reconfig) /* get the initial size */ @@ -288,7 +288,7 @@ void screen_shutdown(gboolean reconfig) { Rect **r; - popup_free(desktop_cycle_popup); + pager_popup_free(desktop_cycle_popup); if (!reconfig) { XSelectInput(ob_display, RootWindow(ob_display, ob_screen), @@ -560,19 +560,18 @@ static void popup_cycle(guint d, gboolean show) Rect *a; if (!show) { - popup_hide(desktop_cycle_popup); + pager_popup_hide(desktop_cycle_popup); } else { a = screen_physical_area_monitor(0); - popup_position(desktop_cycle_popup, CenterGravity, - a->x + a->width / 2, a->y + a->height / 2); + pager_popup_position(desktop_cycle_popup, CenterGravity, + a->x + a->width / 2, a->y + a->height / 2); /* 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, - screen_desktop_names[d], NULL); + pager_popup_show(desktop_cycle_popup, screen_desktop_names[d], d); } } @@ -723,31 +722,39 @@ void screen_update_layout() goto screen_update_layout_bail; } + cols = data[1]; + rows = data[2]; + /* fill in a zero rows/columns */ - if ((data[1] == 0 && data[2] == 0) || /* both 0's is bad data.. */ - (data[1] != 0 && data[2] != 0)) { /* no 0's is bad data.. */ + if ((cols == 0 && rows == 0)) { /* both 0's is bad data.. */ goto screen_update_layout_bail; } else { - if (data[1] == 0) { - data[1] = (screen_num_desktops + - screen_num_desktops % data[2]) / data[2]; - } else if (data[2] == 0) { - data[2] = (screen_num_desktops + - screen_num_desktops % data[1]) / data[1]; + if (cols == 0) { + cols = screen_num_desktops / rows; + if (rows * cols < screen_num_desktops) + cols++; + if (rows * cols >= screen_num_desktops + cols) + 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 */ if (orient == OB_ORIENTATION_HORZ) { - rows = MIN(rows, screen_num_desktops); - cols = MIN(cols, ((screen_num_desktops + - (screen_num_desktops % rows)) / rows)); + cols = MIN(screen_num_desktops, cols); + rows = MIN(rows, (screen_num_desktops + cols - 1) / cols); + cols = screen_num_desktops / rows + + !!(screen_num_desktops % rows); } else { - cols = MIN(cols, screen_num_desktops); - rows = MIN(rows, ((screen_num_desktops + - (screen_num_desktops % cols)) / cols)); + rows = MIN(screen_num_desktops, rows); + cols = MIN(cols, (screen_num_desktops + rows - 1) / rows); + rows = screen_num_desktops / cols + + !!(screen_num_desktops % cols); } valid = TRUE; -- 2.39.2