X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Ffocus_cycle_popup.c;h=ef01ddf47e9ffc73c849a875b7454559db225df6;hb=4c7119f94fe6accb43770aba1a220bed7c627b79;hp=4d6ccdcad1fbb6490dbfd3f7394b2b63c729d049;hpb=50ba7e2d4c1f8df9b18739bac384f64e7717da24;p=chaz%2Fopenbox diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c index 4d6ccdca..ef01ddf4 100644 --- a/openbox/focus_cycle_popup.c +++ b/openbox/focus_cycle_popup.c @@ -30,7 +30,7 @@ #include #include -#define ICON_SIZE 48 +#define ICON_SIZE 40 #define ICON_HILITE_WIDTH 2 #define ICON_HILITE_MARGIN 1 #define OUTSIDE_BORDER 3 @@ -68,12 +68,20 @@ struct _ObFocusCyclePopup 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 all_desktops, - gboolean dock_windows, gboolean desktop_windows); -static void popup_render (ObFocusCyclePopup *p, const 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 Window create_window(Window parent, guint bwidth, gulong mask, XSetWindowAttributes *attr) @@ -87,6 +95,8 @@ void focus_cycle_popup_startup(gboolean reconfig) { 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); @@ -121,6 +131,8 @@ void focus_cycle_popup_startup(gboolean reconfig) void focus_cycle_popup_shutdown(gboolean reconfig) { + icon_popup_free(single_popup); + stacking_remove(INTERNAL_AS_WINDOW(&popup)); while(popup.targets) { @@ -142,7 +154,8 @@ void focus_cycle_popup_shutdown(gboolean reconfig) RrAppearanceFree(popup.a_bg); } -static void popup_setup(ObFocusCyclePopup *p,gboolean all_desktops, +static void popup_setup(ObFocusCyclePopup *p, gboolean create_targets, + gboolean iconic_windows, gboolean all_desktops, gboolean dock_windows, gboolean desktop_windows) { gint maxwidth, n; @@ -161,24 +174,31 @@ static void popup_setup(ObFocusCyclePopup *p,gboolean all_desktops, ObClient *ft = it->data; if (focus_cycle_target_valid(ft, + iconic_windows, all_desktops, 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; + } } } @@ -228,6 +248,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) gint icon_rows; gint textx, texty, textw, texth; gint rgbax, rgbay, rgbaw, rgbah; + gint icons_center_x; gint innerw, innerh; gint i; GList *it; @@ -257,7 +278,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) /* 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? */ @@ -268,7 +289,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) 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; @@ -286,6 +307,12 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) 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); @@ -311,7 +338,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) 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) @@ -379,7 +406,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) 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; @@ -410,7 +437,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) p->last_target = newtarget; } -void focus_cycle_popup_show(ObClient *c, +void focus_cycle_popup_show(ObClient *c, gboolean iconic_windows, gboolean all_desktops, gboolean dock_windows, gboolean desktop_windows) { @@ -418,7 +445,8 @@ void focus_cycle_popup_show(ObClient *c, /* do this stuff only when the dialog is first showing */ if (!popup.mapped) - popup_setup(&popup, all_desktops, dock_windows, desktop_windows); + popup_setup(&popup, TRUE, iconic_windows, all_desktops, + dock_windows, desktop_windows); g_assert(popup.targets != NULL); popup_render(&popup, c); @@ -453,3 +481,40 @@ void focus_cycle_popup_hide() 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); +}