#include "focus_cycle.h"
#include "openbox.h"
#include "window.h"
+#include "event.h"
#include "render/render.h"
#include <X11/Xlib.h>
#include <glib.h>
-#define ICON_SIZE 48
+#define ICON_SIZE 40
#define ICON_HILITE_WIDTH 2
#define ICON_HILITE_MARGIN 1
#define OUTSIDE_BORDER 3
gboolean mapped;
};
+/*! This popup shows all possible windows */
static ObFocusCyclePopup popup;
+/*! 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,
{
XSetWindowAttributes attrib;
+ single_popup = icon_popup_new(TRUE);
+
popup.obwin.type = Window_Internal;
popup.a_bg = RrAppearanceCopy(ob_rr_theme->osd_hilite_bg);
popup.a_text = RrAppearanceCopy(ob_rr_theme->osd_hilite_label);
void focus_cycle_popup_shutdown(gboolean reconfig)
{
+ icon_popup_free(single_popup);
+
stacking_remove(INTERNAL_AS_WINDOW(&popup));
while(popup.targets) {
RrAppearanceFree(popup.a_bg);
}
-static void popup_setup(ObFocusCyclePopup *p,
+static void popup_setup(ObFocusCyclePopup *p, gboolean create_targets,
gboolean iconic_windows, gboolean all_desktops,
gboolean dock_windows, gboolean desktop_windows)
{
dock_windows,
desktop_windows))
{
- ObFocusCyclePopupTarget *t = g_new(ObFocusCyclePopupTarget, 1);
-
- t->client = ft;
- t->text = popup_get_name(ft);
- t->win = create_window(p->bg, 0, 0, NULL);
-
- XMapWindow(ob_display, t->win);
+ gchar *text = popup_get_name(ft);
/* measure */
- p->a_text->texture[0].data.text.string = t->text;
+ p->a_text->texture[0].data.text.string = text;
maxwidth = MAX(maxwidth, RrMinWidth(p->a_text));
- p->targets = g_list_prepend(p->targets, t);
- ++n;
+ if (!create_targets)
+ g_free(text);
+ else {
+ ObFocusCyclePopupTarget *t = g_new(ObFocusCyclePopupTarget, 1);
+
+ t->client = ft;
+ t->text = text;
+ t->win = create_window(p->bg, 0, 0, NULL);
+
+ XMapWindow(ob_display, t->win);
+
+ p->targets = g_list_prepend(p->targets, t);
+ ++n;
+ }
}
}
gint icon_rows;
gint textx, texty, textw, texth;
gint rgbax, rgbay, rgbaw, rgbah;
+ gint icons_center_x;
gint innerw, innerh;
gint i;
GList *it;
/* how many icons will fit in that row? make the width fit that */
w -= l + r;
- icons_per_row = w / ICON_SIZE;
+ icons_per_row = (w + ICON_SIZE - 1) / ICON_SIZE;
w = icons_per_row * ICON_SIZE + l + r;
/* how many rows do we need? */
texth = RrMinHeight(p->a_text);
/* find the height of the dialog */
- h = t + b + (icon_rows * ICON_SIZE) + (OUTSIDE_BORDER + texth);
+ h = t + b + (icon_rows * ICON_SIZE) + (OUTSIDE_BORDER*2 + texth);
/* get the position of the text */
textx = l;
rgbaw = w - ml - mr;
rgbah = h - mt - mb;
+ /* center the icons if there is less than one row */
+ if (icon_rows == 1)
+ icons_center_x = (w - p->n_targets * ICON_SIZE) / 2;
+ else
+ icons_center_x = 0;
+
if (!p->mapped) {
/* position the background but don't draw it*/
XMoveResizeWindow(ob_display, p->bg, x, y, w, h);
/* set up the hilite texture for the background */
p->a_bg->texture[0].data.rgba.width = rgbaw;
p->a_bg->texture[0].data.rgba.height = rgbah;
+ p->a_bg->texture[0].data.rgba.alpha = 0xff;
p->hilite_rgba = g_new(RrPixel32, rgbaw * rgbah);
p->a_bg->texture[0].data.rgba.data = p->hilite_rgba;
if (target->client == c) {
/* save the target */
newtarget = target;
- newtargetx = l + (col * ICON_SIZE);
+ newtargetx = icons_center_x + l + (col * ICON_SIZE);
newtargety = t + (row * ICON_SIZE);
if (!p->mapped)
gint innerx, innery;
/* find the dimensions of the icon inside it */
- innerx = l + (col * ICON_SIZE);
+ innerx = icons_center_x + l + (col * ICON_SIZE);
innerx += ICON_HILITE_WIDTH + ICON_HILITE_MARGIN;
innery = t + (row * ICON_SIZE);
innery += ICON_HILITE_WIDTH + ICON_HILITE_MARGIN;
icon = client_icon(target->client, innerw, innerh);
p->a_icon->texture[0].data.rgba.width = icon->width;
p->a_icon->texture[0].data.rgba.height = icon->height;
+ p->a_icon->texture[0].data.rgba.alpha =
+ target->client->iconic ? OB_ICONIC_ALPHA : 0xff;
p->a_icon->texture[0].data.rgba.data = icon->data;
/* draw the icon */
/* do this stuff only when the dialog is first showing */
if (!popup.mapped)
- popup_setup(&popup, iconic_windows, all_desktops,
+ popup_setup(&popup, TRUE, iconic_windows, all_desktops,
dock_windows, desktop_windows);
g_assert(popup.targets != NULL);
popup.mapped = FALSE;
+ /* kill enter events cause by this unmapping */
+ event_ignore_all_queued_enters();
+
while(popup.targets) {
ObFocusCyclePopupTarget *t = popup.targets->data;
popup.hilite_rgba = NULL;
}
+void focus_cycle_popup_single_show(struct _ObClient *c,
+ gboolean iconic_windows,
+ gboolean all_desktops,
+ gboolean dock_windows,
+ gboolean desktop_windows)
+{
+ gchar *text;
+
+ g_assert(c != NULL);
+
+ /* do this stuff only when the dialog is first showing */
+ if (!popup.mapped) {
+ Rect *a;
+
+ popup_setup(&popup, FALSE, iconic_windows, all_desktops,
+ dock_windows, desktop_windows);
+ g_assert(popup.targets == NULL);
+
+ /* position the popup */
+ a = screen_physical_area_monitor(0);
+ icon_popup_position(single_popup, CenterGravity,
+ a->x + a->width / 2, a->y + a->height / 2);
+ icon_popup_height(single_popup, POPUP_HEIGHT);
+ icon_popup_min_width(single_popup, POPUP_WIDTH);
+ icon_popup_max_width(single_popup, MAX(a->width/3, POPUP_WIDTH));
+ icon_popup_text_width(single_popup, popup.maxtextw);
+ }
+
+ text = popup_get_name(c);
+ icon_popup_show(single_popup, text, client_icon(c, ICON_SIZE, ICON_SIZE));
+ g_free(text);
+}
+
+void focus_cycle_popup_single_hide()
+{
+ icon_popup_hide(single_popup);
+}