popups fixes. if the text for the popup is empty now, there wont be extra padding for it. desktop name fixes.

This commit is contained in:
Dana Jansens 2007-05-07 06:33:43 +00:00
parent 15007a62c2
commit 82b2f0aa7a
7 changed files with 190 additions and 203 deletions

View file

@ -95,6 +95,8 @@
<number>4</number>
<firstdesk>1</firstdesk>
<names>
<!-- the desktop names are only set at startup, pagers allow you to
change them during a session -->
<name>desktop one</name>
<name>desktop two</name>
<name>desktop three</name>

View file

@ -343,6 +343,10 @@ static void popup_cycle(ObClient *c, gboolean show,
icon_popup_position(focus_cycle_popup, CenterGravity,
a->x + a->width / 2, a->y + a->height / 2);
icon_popup_height(focus_cycle_popup, POPUP_HEIGHT);
icon_popup_min_width(focus_cycle_popup, POPUP_WIDTH);
icon_popup_max_width(focus_cycle_popup,
MAX(a->width/3, POPUP_WIDTH));
/* make its width to be the width of all the possible titles */
@ -367,9 +371,7 @@ static void popup_cycle(ObClient *c, gboolean show,
}
names[n] = NULL;
icon_popup_width_to_strings(focus_cycle_popup,
names, n,
MAX(a->width/3, POPUP_WIDTH));
icon_popup_text_width_to_strings(focus_cycle_popup, names, n);
g_strfreev(names);
}
@ -528,47 +530,45 @@ static gboolean valid_focus_target(ObClient *ft,
gboolean dock_windows)
{
gboolean ok = FALSE;
/* we don't use client_can_focus here, because that doesn't let you
focus an iconic window, but we want to be able to, so we just check
if the focus flags on the window allow it, and its on the current
desktop */
if (dock_windows)
ok = ft->type == OB_CLIENT_TYPE_DOCK;
else
ok = (ft->type == OB_CLIENT_TYPE_NORMAL ||
ft->type == OB_CLIENT_TYPE_DIALOG ||
((ft->type == OB_CLIENT_TYPE_TOOLBAR ||
ft->type == OB_CLIENT_TYPE_MENU ||
ft->type == OB_CLIENT_TYPE_UTILITY) &&
/* let alt-tab go to these windows when a window in its group
already has focus ... */
((focus_client && ft->group == focus_client->group) ||
/* ... or if there are no application windows in its group */
!client_has_application_group_siblings(ft))));
/* it's on this desktop unless you want all desktops.
do this check first because it will usually filter out the most
windows */
ok = (all_desktops || ft->desktop == screen_desktop ||
ft->desktop == DESKTOP_ALL);
/* the window can receive focus somehow */
ok = ok && (ft->can_focus || ft->focus_notify);
if (!dock_windows && /* use dock windows that skip taskbar too */
!(ft->type == OB_CLIENT_TYPE_TOOLBAR || /* also, if we actually are */
ft->type == OB_CLIENT_TYPE_MENU || /* being allowed to target */
ft->type == OB_CLIENT_TYPE_UTILITY)) /* one of these, don't let */
ok = ok && !ft->skip_taskbar; /* skip taskbar stop us */
if (!all_desktops)
ok = ok && (ft->desktop == screen_desktop ||
ft->desktop == DESKTOP_ALL);
/* it's the right type of window */
if (dock_windows)
ok = ok && ft->type == OB_CLIENT_TYPE_DOCK;
else
ok = ok && (ft->type == OB_CLIENT_TYPE_NORMAL ||
ft->type == OB_CLIENT_TYPE_DIALOG ||
((ft->type == OB_CLIENT_TYPE_TOOLBAR ||
ft->type == OB_CLIENT_TYPE_MENU ||
ft->type == OB_CLIENT_TYPE_UTILITY) &&
/* let alt-tab go to these windows when a window in its
group already has focus ... */
((focus_client && ft->group == focus_client->group) ||
/* ... or if there are no application windows in its
group */
!client_has_application_group_siblings(ft))));
/* it's not set to skip the taskbar (unless it is a type that would be
expected to set this hint */
ok = ok && (!(ft->type == OB_CLIENT_TYPE_DOCK ||
ft->type == OB_CLIENT_TYPE_TOOLBAR ||
ft->type == OB_CLIENT_TYPE_MENU ||
ft->type == OB_CLIENT_TYPE_UTILITY) ||
!ft->skip_taskbar);
/* it's not going to just send fous off somewhere else (modal window) */
ok = ok && ft == client_focus_target(ft);
return ok;
/*
{
GSList *it;
for (it = ft->transients; it; it = g_slist_next(it)) {
ObClient *c = it->data;
if (frame_visible(c->frame))
return FALSE;
}
return TRUE;
}
*/
}
void focus_cycle(gboolean forward, gboolean all_desktops,

View file

@ -29,27 +29,14 @@
#include "render/render.h"
#include "render/theme.h"
static gboolean popup_show_timeout(gpointer data)
{
ObPopup *self = data;
XMapWindow(ob_display, self->bg);
stacking_raise(INTERNAL_AS_WINDOW(self));
self->mapped = TRUE;
self->delay_mapped = FALSE;
return FALSE; /* don't repeat */
}
ObPopup *popup_new(gboolean hasicon)
ObPopup *popup_new()
{
XSetWindowAttributes attrib;
ObPopup *self = g_new0(ObPopup, 1);
self->obwin.type = Window_Internal;
self->hasicon = hasicon;
self->gravity = NorthWestGravity;
self->x = self->y = self->w = self->h = 0;
self->x = self->y = self->textw = self->h = 0;
self->a_bg = RrAppearanceCopy(ob_rr_theme->osd_hilite_bg);
self->a_text = RrAppearanceCopy(ob_rr_theme->osd_hilite_label);
@ -63,6 +50,9 @@ ObPopup *popup_new(gboolean hasicon)
0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
InputOutput, RrVisual(ob_rr_inst), 0, NULL);
XSetWindowBorderWidth(ob_display, self->bg, ob_rr_theme->fbwidth);
XSetWindowBorder(ob_display, self->bg, ob_rr_theme->frame_b_color->pixel);
XMapWindow(ob_display, self->text);
stacking_add(INTERNAL_AS_WINDOW(self));
@ -88,10 +78,19 @@ void popup_position(ObPopup *self, gint gravity, gint x, gint y)
self->y = y;
}
void popup_width(ObPopup *self, gint w)
void popup_text_width(ObPopup *self, gint w)
{
self->w = w;
self->maxw = w;
self->textw = w;
}
void popup_min_width(ObPopup *self, gint minw)
{
self->minw = minw;
}
void popup_max_width(ObPopup *self, gint maxw)
{
self->maxw = maxw;
}
void popup_height(ObPopup *self, gint h)
@ -103,11 +102,13 @@ void popup_height(ObPopup *self, gint h)
self->h = MAX(h, texth);
}
void popup_width_to_string(ObPopup *self, gchar *text, gint max)
void popup_text_width_to_string(ObPopup *self, gchar *text)
{
self->a_text->texture[0].data.text.string = text;
self->w = RrMinWidth(self->a_text);
self->maxw = max;
if (text[0] != '\0') {
self->a_text->texture[0].data.text.string = text;
self->textw = RrMinWidth(self->a_text);
} else
self->textw = 0;
}
void popup_height_to_string(ObPopup *self, gchar *text)
@ -115,16 +116,16 @@ void popup_height_to_string(ObPopup *self, gchar *text)
self->h = RrMinHeight(self->a_text) + ob_rr_theme->paddingy * 2;
}
void popup_width_to_strings(ObPopup *self, gchar **strings, gint num, gint max)
void popup_text_width_to_strings(ObPopup *self, gchar **strings, gint num)
{
gint i, maxw;
maxw = 0;
for (i = 0; i < num; ++i) {
popup_width_to_string(self, strings[i], max);
maxw = MAX(maxw, self->w);
popup_text_width_to_string(self, strings[i]);
maxw = MAX(maxw, self->textw);
}
self->w = maxw;
self->textw = maxw;
}
void popup_set_text_align(ObPopup *self, RrJustify align)
@ -132,70 +133,80 @@ void popup_set_text_align(ObPopup *self, RrJustify align)
self->a_text->texture[0].data.text.justify = align;
}
static gboolean popup_show_timeout(gpointer data)
{
ObPopup *self = data;
XMapWindow(ob_display, self->bg);
stacking_raise(INTERNAL_AS_WINDOW(self));
self->mapped = TRUE;
self->delay_mapped = FALSE;
return FALSE; /* don't repeat */
}
void popup_delay_show(ObPopup *self, gulong usec, gchar *text)
{
gint l, t, r, b;
gint x, y, w, h;
gint xpadding, ypadding;
gint textw, texth;
gint iconw;
Rect *area; /* won't go outside this */
area = screen_physical_area(); /* XXX this should work quite
good, someone with xinerama,
and different resolutions on
screens? */
gint emptyx, emptyy; /* empty space between elements */
gint textx, texty, textw, texth;
gint iconx, icony, iconw, iconh;
RrMargins(self->a_bg, &l, &t, &r, &b);
XSetWindowBorderWidth(ob_display, self->bg, ob_rr_theme->fbwidth);
XSetWindowBorder(ob_display, self->bg, ob_rr_theme->frame_b_color->pixel);
/* set up the textures */
self->a_text->texture[0].data.text.string = text;
/* measure the text out */
RrMinSize(self->a_text, &textw, &texth);
texth += ob_rr_theme->paddingy * 2;
if (text[0] != '\0') {
RrMinSize(self->a_text, &textw, &texth);
} else {
textw = 0;
texth = RrMinHeight(self->a_text);
}
ypadding = (t+b + ob_rr_theme->paddingy * 2);
/* set the sizes up and reget the text sizes from the calculated
outer sizes */
/* get the height, which is also used for the icon width */
emptyy = t + b + ob_rr_theme->paddingy * 2;
if (self->h) {
h = self->h;
texth = h - ypadding;
texth = h - emptyy;
} else
h = texth + ypadding;
h = texth + emptyy;
iconw = (self->hasicon ? texth : 0);
xpadding = l+r + iconw + ob_rr_theme->paddingx *
(self->hasicon ? 3 : 2);
if (self->textw)
textw = self->textw;
if (self->w)
textw = self->w;
w = textw + xpadding;
/* cap it at "maxw" */
iconx = textx = l + ob_rr_theme->paddingx;
icony = texty = t + ob_rr_theme->paddingy;
emptyx = l + r + ob_rr_theme->paddingx * 2;
if (self->hasicon) {
iconw = iconh = texth;
textx += iconw + ob_rr_theme->paddingx;
if (textw)
emptyx += ob_rr_theme->paddingx; /* between the icon and text */
} else
iconw = 0;
w = textw + emptyx + iconw;
/* cap it at maxw/minw */
if (self->maxw) w = MIN(w, self->maxw);
textw = w - xpadding;
if (self->minw) w = MAX(w, self->minw);
textw = w - emptyx - iconw;
/* 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:
case NorthGravity: case CenterGravity: case SouthGravity:
x -= w / 2;
break;
case NorthEastGravity:
case EastGravity:
case SouthEastGravity:
case NorthEastGravity: case EastGravity: case SouthEastGravity:
x -= w;
break;
}
@ -203,44 +214,29 @@ void popup_delay_show(ObPopup *self, gulong usec, gchar *text)
/* set up the y coord */
y = self->y;
switch (self->gravity) {
case WestGravity:
case CenterGravity:
case EastGravity:
case WestGravity: case CenterGravity: case EastGravity:
y -= h / 2;
break;
case SouthWestGravity:
case SouthGravity:
case SouthEastGravity:
case SouthWestGravity: case SouthGravity: case SouthEastGravity:
y -= h;
break;
}
x=MAX(MIN(x, area->width-w),0);
y=MAX(MIN(y, area->height-h),0);
/* set the windows/appearances up */
XMoveResizeWindow(ob_display, self->bg, x, y, w, h);
self->a_text->surface.parent = self->a_bg;
self->a_text->surface.parentx = l + iconw +
ob_rr_theme->paddingx * (self->hasicon ? 2 : 1);
self->a_text->surface.parenty = t + ob_rr_theme->paddingy;
XMoveResizeWindow(ob_display, self->text,
l + iconw + ob_rr_theme->paddingx *
(self->hasicon ? 2 : 1),
t + ob_rr_theme->paddingy, 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 */
if (self->draw_icon)
self->draw_icon(l + ob_rr_theme->paddingx,
t + ob_rr_theme->paddingy,
iconw, texth, self->draw_icon_data);
if (textw) {
self->a_text->surface.parent = self->a_bg;
self->a_text->surface.parentx = textx;
self->a_text->surface.parenty = texty;
XMoveResizeWindow(ob_display, self->text, textx, texty, textw, texth);
RrPaint(self->a_text, self->text, textw, texth);
}
if (self->hasicon)
self->draw_icon(iconx, icony, iconw, iconh, self->draw_icon_data);
/* do the actual showing */
if (!self->mapped) {
if (usec) {
@ -295,6 +291,7 @@ ObIconPopup *icon_popup_new()
RrVisual(ob_rr_inst), 0, NULL);
XMapWindow(ob_display, self->icon);
self->popup->hasicon = TRUE;
self->popup->draw_icon = icon_popup_draw_icon;
self->popup->draw_icon_data = self;
@ -335,21 +332,18 @@ static void pager_popup_draw_icon(gint px, gint py, gint w, gint h,
guint vert_inc;
guint r, c;
gint eachw, eachh;
const guint cols = screen_desktop_layout.columns;
const guint rows = screen_desktop_layout.rows;
const gint linewidth = ob_rr_theme->fbwidth;
eachw = (w - ob_rr_theme->fbwidth -
(screen_desktop_layout.columns * ob_rr_theme->fbwidth))
/ screen_desktop_layout.columns;
eachh = (h - ob_rr_theme->fbwidth -
(screen_desktop_layout.rows * ob_rr_theme->fbwidth))
/ screen_desktop_layout.rows;
eachw = (w - ((cols + 1) * linewidth)) / cols;
eachh = (h - ((rows + 1) * linewidth)) / rows;
/* make them squares */
eachw = eachh = MIN(eachw, eachh);
/* center */
px += (w - (screen_desktop_layout.columns * (eachw + ob_rr_theme->fbwidth) +
ob_rr_theme->fbwidth)) / 2;
py += (h - (screen_desktop_layout.rows * (eachh + ob_rr_theme->fbwidth) +
ob_rr_theme->fbwidth)) / 2;
px += (w - (cols * (eachw + linewidth) + linewidth)) / 2;
py += (h - (rows * (eachh + linewidth) + linewidth)) / 2;
if (eachw <= 0 || eachh <= 0)
return;
@ -360,23 +354,22 @@ static void pager_popup_draw_icon(gint px, gint py, gint w, gint h,
case OB_CORNER_TOPLEFT:
n = 0;
horz_inc = 1;
vert_inc = screen_desktop_layout.columns;
vert_inc = cols;
break;
case OB_CORNER_TOPRIGHT:
n = screen_desktop_layout.columns - 1;
n = cols - 1;
horz_inc = -1;
vert_inc = screen_desktop_layout.columns;
vert_inc = cols;
break;
case OB_CORNER_BOTTOMRIGHT:
n = screen_desktop_layout.rows * screen_desktop_layout.columns - 1;
n = rows * cols - 1;
horz_inc = -1;
vert_inc = -screen_desktop_layout.columns;
break;
case OB_CORNER_BOTTOMLEFT:
n = (screen_desktop_layout.rows - 1)
* screen_desktop_layout.columns;
n = (rows - 1) * cols;
horz_inc = 1;
vert_inc = -screen_desktop_layout.columns;
vert_inc = -cols;
break;
default:
g_assert_not_reached();
@ -386,23 +379,22 @@ static void pager_popup_draw_icon(gint px, gint py, gint w, gint h,
switch (screen_desktop_layout.start_corner) {
case OB_CORNER_TOPLEFT:
n = 0;
horz_inc = screen_desktop_layout.rows;
horz_inc = rows;
vert_inc = 1;
break;
case OB_CORNER_TOPRIGHT:
n = screen_desktop_layout.rows
* (screen_desktop_layout.columns - 1);
horz_inc = -screen_desktop_layout.rows;
n = rows * (cols - 1);
horz_inc = -rows;
vert_inc = 1;
break;
case OB_CORNER_BOTTOMRIGHT:
n = screen_desktop_layout.rows * screen_desktop_layout.columns - 1;
horz_inc = -screen_desktop_layout.rows;
n = rows * cols - 1;
horz_inc = -rows;
vert_inc = -1;
break;
case OB_CORNER_BOTTOMLEFT:
n = screen_desktop_layout.rows - 1;
horz_inc = screen_desktop_layout.rows;
n = rows - 1;
horz_inc = rows;
vert_inc = -1;
break;
default:
@ -414,11 +406,9 @@ static void pager_popup_draw_icon(gint px, gint py, gint w, gint h,
}
rown = n;
for (r = 0, y = 0; r < screen_desktop_layout.rows;
++r, y += eachh + ob_rr_theme->fbwidth)
for (r = 0, y = 0; r < rows; ++r, y += eachh + linewidth)
{
for (c = 0, x = 0; c < screen_desktop_layout.columns;
++c, x += eachw + ob_rr_theme->fbwidth)
for (c = 0, x = 0; c < cols; ++c, x += eachw + linewidth)
{
RrAppearance *a;

View file

@ -45,8 +45,9 @@ struct _ObPopup
gint gravity;
gint x;
gint y;
gint w;
gint textw;
gint h;
gint minw;
gint maxw;
gboolean mapped;
gboolean delay_mapped;
@ -74,7 +75,7 @@ struct _ObPagerPopup
RrAppearance *unhilight;
};
ObPopup *popup_new(gboolean hasicon);
ObPopup *popup_new();
void popup_free(ObPopup *self);
/*! Position the popup. The gravity rules are not the same X uses for windows,
@ -85,11 +86,13 @@ void popup_free(ObPopup *self);
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_width(ObPopup *self, gint w);
void popup_height(ObPopup *self, gint w);
void popup_width_to_string(ObPopup *self, gchar *text, gint max);
void popup_min_width(ObPopup *self, gint minw);
void popup_max_width(ObPopup *self, gint maxw);
void popup_text_width(ObPopup *self, gint w);
void popup_text_width_to_string(ObPopup *self, gchar *text);
void popup_height_to_string(ObPopup *self, gchar *text);
void popup_width_to_strings(ObPopup *self, gchar **strings, gint num,gint max);
void popup_text_width_to_strings(ObPopup *self, gchar **strings, gint num);
void popup_set_text_align(ObPopup *self, RrJustify align);
@ -108,12 +111,14 @@ void icon_popup_delay_show(ObIconPopup *self, gulong usec,
gchar *text, const 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_width(p, w) popup_width((p)->popup,(w))
#define icon_popup_text_width(p, w) popup_text_width((p)->popup,(w))
#define icon_popup_height(p, h) popup_height((p)->popup,(h))
#define icon_popup_width_to_string(p, s, n, m) \
popup_width_to_string((p)->popup,(s),(n),(m))
#define icon_popup_width_to_strings(p, s, n, m) \
popup_width_to_strings((p)->popup,(s),(n),(m))
#define icon_popup_min_width(p, m) popup_min_width((p)->popup,(m))
#define icon_popup_max_width(p, m) popup_max_width((p)->popup,(m))
#define icon_popup_text_width_to_string(p, s) \
popup_text_width_to_string((p)->popup,(s))
#define icon_popup_text_width_to_strings(p, s, n) \
popup_text_width_to_strings((p)->popup,(s),(n))
#define icon_popup_set_text_align(p, j) popup_set_text_align((p)->popup,(j))
ObPagerPopup *pager_popup_new();
@ -124,12 +129,14 @@ void pager_popup_delay_show(ObPagerPopup *self, gulong usec,
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_width(p, w) popup_width((p)->popup,(w))
#define pager_popup_text_width(p, w) popup_text_width((p)->popup,(w))
#define pager_popup_height(p, h) popup_height((p)->popup,(h))
#define pager_popup_width_to_string(p, s, n, m) \
popup_width_to_string((p)->popup,(s),(n),(m))
#define pager_popup_width_to_strings(p, s, n, m) \
popup_width_to_strings((p)->popup,(s),(n),(m))
#define pager_popup_min_width(p, m) popup_min_width((p)->popup,(m))
#define pager_popup_max_width(p, m) popup_max_width((p)->popup,(m))
#define pager_popup_text_width_to_string(p, s) \
popup_text_width_to_string((p)->popup,(s))
#define pager_popup_text_width_to_strings(p, s, n) \
popup_text_width_to_strings((p)->popup,(s),(n))
#define pager_popup_set_text_align(p, j) popup_set_text_align((p)->popup,(j))
#endif

View file

@ -299,42 +299,30 @@ gboolean screen_annex(const gchar *program_name)
void screen_startup(gboolean reconfig)
{
guint i, numnames;
if (!reconfig) {
guint i, numnames;
gchar **names;
GSList *it;
if (!reconfig)
/* get the initial size */
screen_resize();
/* get the desktop names */
numnames = g_slist_length(config_desktops_names);
names = g_new(gchar*, numnames + 1);
names[numnames] = NULL;
for (i = 0, it = config_desktops_names; it; ++i, it = g_slist_next(it))
names[i] = g_strdup(it->data);
/* set the root window property */
PROP_SETSS(RootWindow(ob_display, ob_screen), net_desktop_names,names);
g_strfreev(names);
}
desktop_cycle_popup = pager_popup_new(FALSE);
pager_popup_height(desktop_cycle_popup, POPUP_HEIGHT);
#if 0
/* get the names */
if (PROP_GETSS(RootWindow(ob_display, ob_screen),
net_desktop_names, utf8, &screen_desktop_names))
for (i = 0; screen_desktop_names[i]; ++i);
else
#endif
i = 0;
numnames = g_slist_length(config_desktops_names);
if (numnames > i) {
GSList *it;
screen_desktop_names = g_renew(gchar*,screen_desktop_names,numnames+1);
screen_desktop_names[numnames] = NULL;
for (it = g_slist_nth(config_desktops_names, i); it;
it = g_slist_next(it), ++i)
{
screen_desktop_names[i] = g_strdup(it->data);
}
}
/* then set the names */
PROP_SETSS(RootWindow(ob_display, ob_screen),
net_desktop_names, screen_desktop_names);
g_strfreev(screen_desktop_names);
screen_desktop_names = NULL;
if (!reconfig)
screen_num_desktops = 0;
screen_set_num_desktops(config_desktops_num);

View file

@ -137,7 +137,7 @@ static void font_measure_full(const RrFont *f, const gchar *str,
pango_layout_set_text(f->layout, str, -1);
pango_layout_set_width(f->layout, -1);
pango_layout_get_pixel_extents(f->layout, NULL, &rect);
*x = rect.width + ABS(shadow_x);
*x = rect.width + ABS(shadow_x) + 4 /* we put a 2 px edge on each side */;
*y = rect.height + ABS(shadow_y);
}

View file

@ -369,7 +369,7 @@ gint RrMinWidth(RrAppearance *a)
a->texture[i].data.text.string,
a->texture[i].data.text.shadow_offset_x,
a->texture[i].data.text.shadow_offset_y);
w = MAX(w, m->width + 4);
w = MAX(w, m->width);
g_free(m);
break;
case RR_TEXTURE_RGBA: