/*! This popup shows a single window */
static ObIconPopup *single_popup;
-static gchar *popup_get_name (ObClient *c);
-static void popup_setup (ObFocusCyclePopup *p,
- gboolean create_targets,
- gboolean iconic_windows,
- gboolean all_desktops,
- gboolean dock_windows,
- gboolean desktop_windows);
-static void popup_render (ObFocusCyclePopup *p,
- const ObClient *c);
+static gchar *popup_get_name (ObClient *c);
+static gboolean popup_setup (ObFocusCyclePopup *p,
+ gboolean create_targets,
+ gboolean refresh_targets,
+ gboolean iconic_windows,
+ gboolean all_desktops,
+ gboolean dock_windows,
+ gboolean desktop_windows);
+static void popup_render (ObFocusCyclePopup *p,
+ const ObClient *c);
static Window create_window(Window parent, guint bwidth, gulong mask,
XSetWindowAttributes *attr)
RrAppearanceFree(popup.a_bg);
}
-static void popup_setup(ObFocusCyclePopup *p, gboolean create_targets,
- gboolean iconic_windows, gboolean all_desktops,
- gboolean dock_windows, gboolean desktop_windows)
+static void popup_target_free(ObFocusCyclePopupTarget *t)
+{
+ RrImageUnref(t->icon);
+ g_free(t->text);
+ XDestroyWindow(ob_display, t->win);
+ g_free(t);
+}
+
+static gboolean popup_setup(ObFocusCyclePopup *p, gboolean create_targets,
+ gboolean refresh_targets,
+ gboolean iconic_windows, gboolean all_desktops,
+ gboolean dock_windows, gboolean desktop_windows)
{
gint maxwidth, n;
GList *it;
+ GList *rtargets; /* old targets for refresh */
+ GList *rtlast;
+ gboolean change;
+
+ if (refresh_targets) {
+ rtargets = p->targets;
+ rtlast = g_list_last(rtargets);
+ p->targets = NULL;
+ p->n_targets = 0;
+ change = FALSE;
+ }
+ else {
+ rtargets = rtlast = NULL;
+ change = TRUE;
+ }
g_assert(p->targets == NULL);
g_assert(p->n_targets == 0);
desktop_windows,
FALSE))
{
- gchar *text = popup_get_name(ft);
+ GList *rit;
+
+ /* reuse the target if possible during refresh */
+ for (rit = rtlast; rit; rit = g_list_previous(rit)) {
+ ObFocusCyclePopupTarget *t = rit->data;
+ if (t->client == ft) {
+ if (rit == rtlast)
+ rtlast = g_list_previous(rit);
+ rtargets = g_list_remove_link(rtargets, rit);
+
+ p->targets = g_list_concat(rit, p->targets);
+ ++n;
+
+ if (rit != rtlast)
+ change = TRUE; /* order changed */
+ break;
+ }
+ }
+
+ if (!rit) {
+ gchar *text = popup_get_name(ft);
- /* measure */
- p->a_text->texture[0].data.text.string = text;
- maxwidth = MAX(maxwidth, RrMinWidth(p->a_text));
+ /* measure */
+ p->a_text->texture[0].data.text.string = text;
+ maxwidth = MAX(maxwidth, RrMinWidth(p->a_text));
- if (!create_targets)
- g_free(text);
- else {
- ObFocusCyclePopupTarget *t = g_new(ObFocusCyclePopupTarget, 1);
+ if (!create_targets)
+ g_free(text);
+ else {
+ ObFocusCyclePopupTarget *t =
+ g_new(ObFocusCyclePopupTarget, 1);
+
+ t->client = ft;
+ t->text = text;
+ t->icon = client_icon(t->client);
+ RrImageRef(t->icon); /* own the icon so it won't go away */
+ t->win = create_window(p->bg, 0, 0, NULL);
- t->client = ft;
- t->text = text;
- t->icon = client_icon(t->client);
- RrImageRef(t->icon); /* own the icon so it won't go away */
- t->win = create_window(p->bg, 0, 0, NULL);
+ XMapWindow(ob_display, t->win);
- XMapWindow(ob_display, t->win);
+ p->targets = g_list_prepend(p->targets, t);
+ ++n;
- p->targets = g_list_prepend(p->targets, t);
- ++n;
+ change = TRUE; /* added a window */
+ }
}
}
}
+ if (rtargets) {
+ change = TRUE; /* removed a window */
+
+ while (rtargets) {
+ popup_target_free(rtargets->data);
+ rtargets = g_list_delete_link(rtargets, rtargets);
+
+ popup.targets = g_list_delete_link(popup.targets, popup.targets);
+ }
+ }
+
p->n_targets = n;
p->maxtextw = maxwidth;
+
+ return change;
}
static void popup_cleanup(void)
{
while(popup.targets) {
- ObFocusCyclePopupTarget *t = popup.targets->data;
-
- RrImageUnref(t->icon);
- g_free(t->text);
- XDestroyWindow(ob_display, t->win);
- g_free(t);
-
+ popup_target_free(popup.targets->data);
popup.targets = g_list_delete_link(popup.targets, popup.targets);
}
popup.n_targets = 0;
/* do this stuff only when the dialog is first showing */
if (!popup.mapped)
- popup_setup(&popup, TRUE, iconic_windows, all_desktops,
+ popup_setup(&popup, TRUE, FALSE, iconic_windows, all_desktops,
dock_windows, desktop_windows);
g_assert(popup.targets != NULL);
if (!popup.mapped) {
Rect *a;
- popup_setup(&popup, FALSE, iconic_windows, all_desktops,
+ popup_setup(&popup, FALSE, FALSE, iconic_windows, all_desktops,
dock_windows, desktop_windows);
g_assert(popup.targets == NULL);
{
if (!popup.mapped) return;
- popup_cleanup();
- popup_setup(&popup, TRUE, iconic_windows, all_desktops,
- dock_windows, desktop_windows);
-
- popup.mapped = FALSE;
- popup_render(&popup, target);
- XFlush(ob_display);
- popup.mapped = TRUE;
+ if (popup_setup(&popup, TRUE, TRUE, iconic_windows, all_desktops,
+ dock_windows, desktop_windows))
+ {
+ popup.mapped = FALSE;
+ popup_render(&popup, target);
+ XFlush(ob_display);
+ popup.mapped = TRUE;
+ }
}