--- /dev/null
+/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
+
+ focus_cycle_indicator.c for the Openbox window manager
+ Copyright (c) 2006 Mikael Magnusson
+ Copyright (c) 2003-2007 Dana Jansens
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ See the COPYING file for a copy of the GNU General Public License.
+*/
+
+#include "focus_cycle.h"
+#include "client.h"
+#include "openbox.h"
+#include "frame.h"
+#include "event.h"
+#include "render/render.h"
+
+#include <X11/Xlib.h>
+#include <glib.h>
+
+#define FOCUS_INDICATOR_WIDTH 6
+
+struct
+{
+ InternalWindow top;
+ InternalWindow left;
+ InternalWindow right;
+ InternalWindow bottom;
+} focus_indicator;
+
+static RrAppearance *a_focus_indicator;
+static RrColor *color_white;
+
+static Window create_window(Window parent, gulong mask,
+ XSetWindowAttributes *attrib)
+{
+ return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
+ RrDepth(ob_rr_inst), InputOutput,
+ RrVisual(ob_rr_inst), mask, attrib);
+
+}
+
+void focus_cycle_indicator_startup(gboolean reconfig)
+{
+ XSetWindowAttributes attr;
+
+ if (reconfig) return;
+
+ focus_indicator.top.obwin.type = Window_Internal;
+ focus_indicator.left.obwin.type = Window_Internal;
+ focus_indicator.right.obwin.type = Window_Internal;
+ focus_indicator.bottom.obwin.type = Window_Internal;
+
+ attr.override_redirect = True;
+ attr.background_pixel = BlackPixel(ob_display, ob_screen);
+ focus_indicator.top.win =
+ create_window(RootWindow(ob_display, ob_screen),
+ CWOverrideRedirect | CWBackPixel, &attr);
+ focus_indicator.left.win =
+ create_window(RootWindow(ob_display, ob_screen),
+ CWOverrideRedirect | CWBackPixel, &attr);
+ focus_indicator.right.win =
+ create_window(RootWindow(ob_display, ob_screen),
+ CWOverrideRedirect | CWBackPixel, &attr);
+ focus_indicator.bottom.win =
+ create_window(RootWindow(ob_display, ob_screen),
+ CWOverrideRedirect | CWBackPixel, &attr);
+
+ stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.top));
+ stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.left));
+ stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.right));
+ stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.bottom));
+
+ color_white = RrColorNew(ob_rr_inst, 0xff, 0xff, 0xff);
+
+ a_focus_indicator = RrAppearanceNew(ob_rr_inst, 4);
+ a_focus_indicator->surface.grad = RR_SURFACE_SOLID;
+ a_focus_indicator->surface.relief = RR_RELIEF_FLAT;
+ a_focus_indicator->surface.primary = RrColorNew(ob_rr_inst,
+ 0, 0, 0);
+ a_focus_indicator->texture[0].type = RR_TEXTURE_LINE_ART;
+ a_focus_indicator->texture[0].data.lineart.color = color_white;
+ a_focus_indicator->texture[1].type = RR_TEXTURE_LINE_ART;
+ a_focus_indicator->texture[1].data.lineart.color = color_white;
+ a_focus_indicator->texture[2].type = RR_TEXTURE_LINE_ART;
+ a_focus_indicator->texture[2].data.lineart.color = color_white;
+ a_focus_indicator->texture[3].type = RR_TEXTURE_LINE_ART;
+ a_focus_indicator->texture[3].data.lineart.color = color_white;
+}
+
+void focus_cycle_indicator_shutdown(gboolean reconfig)
+{
+ if (reconfig) return;
+
+ RrColorFree(color_white);
+
+ RrAppearanceFree(a_focus_indicator);
+
+ XDestroyWindow(ob_display, focus_indicator.top.win);
+ XDestroyWindow(ob_display, focus_indicator.left.win);
+ XDestroyWindow(ob_display, focus_indicator.right.win);
+ XDestroyWindow(ob_display, focus_indicator.bottom.win);
+}
+
+void focus_cycle_draw_indicator(ObClient *c)
+{
+ if (!c) {
+ XUnmapWindow(ob_display, focus_indicator.top.win);
+ XUnmapWindow(ob_display, focus_indicator.left.win);
+ XUnmapWindow(ob_display, focus_indicator.right.win);
+ XUnmapWindow(ob_display, focus_indicator.bottom.win);
+
+ /* kill enter events cause by this unmapping */
+ event_ignore_all_queued_enters();
+ } else {
+ /*
+ if (c)
+ frame_adjust_focus(c->frame, FALSE);
+ frame_adjust_focus(c->frame, TRUE);
+ */
+ gint x, y, w, h;
+ gint wt, wl, wr, wb;
+
+ wt = wl = wr = wb = FOCUS_INDICATOR_WIDTH;
+
+ x = c->frame->area.x;
+ y = c->frame->area.y;
+ w = c->frame->area.width;
+ h = wt;
+
+ XMoveResizeWindow(ob_display, focus_indicator.top.win,
+ x, y, w, h);
+ a_focus_indicator->texture[0].data.lineart.x1 = 0;
+ a_focus_indicator->texture[0].data.lineart.y1 = h-1;
+ a_focus_indicator->texture[0].data.lineart.x2 = 0;
+ a_focus_indicator->texture[0].data.lineart.y2 = 0;
+ a_focus_indicator->texture[1].data.lineart.x1 = 0;
+ a_focus_indicator->texture[1].data.lineart.y1 = 0;
+ a_focus_indicator->texture[1].data.lineart.x2 = w-1;
+ a_focus_indicator->texture[1].data.lineart.y2 = 0;
+ a_focus_indicator->texture[2].data.lineart.x1 = w-1;
+ a_focus_indicator->texture[2].data.lineart.y1 = 0;
+ a_focus_indicator->texture[2].data.lineart.x2 = w-1;
+ a_focus_indicator->texture[2].data.lineart.y2 = h-1;
+ a_focus_indicator->texture[3].data.lineart.x1 = (wl-1);
+ a_focus_indicator->texture[3].data.lineart.y1 = h-1;
+ a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
+ a_focus_indicator->texture[3].data.lineart.y2 = h-1;
+ RrPaint(a_focus_indicator, focus_indicator.top.win,
+ w, h);
+
+ x = c->area.x;
+ y = c->frame->area.y;
+ w = wl;
+ h = c->frame->area.height;
+
+ XMoveResizeWindow(ob_display, focus_indicator.left.win,
+ x, y, w, h);
+ a_focus_indicator->texture[0].data.lineart.x1 = w-1;
+ a_focus_indicator->texture[0].data.lineart.y1 = 0;
+ a_focus_indicator->texture[0].data.lineart.x2 = 0;
+ a_focus_indicator->texture[0].data.lineart.y2 = 0;
+ a_focus_indicator->texture[1].data.lineart.x1 = 0;
+ a_focus_indicator->texture[1].data.lineart.y1 = 0;
+ a_focus_indicator->texture[1].data.lineart.x2 = 0;
+ a_focus_indicator->texture[1].data.lineart.y2 = h-1;
+ a_focus_indicator->texture[2].data.lineart.x1 = 0;
+ a_focus_indicator->texture[2].data.lineart.y1 = h-1;
+ a_focus_indicator->texture[2].data.lineart.x2 = w-1;
+ a_focus_indicator->texture[2].data.lineart.y2 = h-1;
+ a_focus_indicator->texture[3].data.lineart.x1 = w-1;
+ a_focus_indicator->texture[3].data.lineart.y1 = wt-1;
+ a_focus_indicator->texture[3].data.lineart.x2 = w-1;
+ a_focus_indicator->texture[3].data.lineart.y2 = h - wb;
+ RrPaint(a_focus_indicator, focus_indicator.left.win,
+ w, h);
+
+ x = c->frame->area.x + c->frame->area.width - wr;
+ y = c->frame->area.y;
+ w = wr;
+ h = c->frame->area.height ;
+
+ XMoveResizeWindow(ob_display, focus_indicator.right.win,
+ x, y, w, h);
+ a_focus_indicator->texture[0].data.lineart.x1 = 0;
+ a_focus_indicator->texture[0].data.lineart.y1 = 0;
+ a_focus_indicator->texture[0].data.lineart.x2 = w-1;
+ a_focus_indicator->texture[0].data.lineart.y2 = 0;
+ a_focus_indicator->texture[1].data.lineart.x1 = w-1;
+ a_focus_indicator->texture[1].data.lineart.y1 = 0;
+ a_focus_indicator->texture[1].data.lineart.x2 = w-1;
+ a_focus_indicator->texture[1].data.lineart.y2 = h-1;
+ a_focus_indicator->texture[2].data.lineart.x1 = w-1;
+ a_focus_indicator->texture[2].data.lineart.y1 = h-1;
+ a_focus_indicator->texture[2].data.lineart.x2 = 0;
+ a_focus_indicator->texture[2].data.lineart.y2 = h-1;
+ a_focus_indicator->texture[3].data.lineart.x1 = 0;
+ a_focus_indicator->texture[3].data.lineart.y1 = wt-1;
+ a_focus_indicator->texture[3].data.lineart.x2 = 0;
+ a_focus_indicator->texture[3].data.lineart.y2 = h - wb;
+ RrPaint(a_focus_indicator, focus_indicator.right.win,
+ w, h);
+
+ x = c->frame->area.x;
+ y = c->frame->area.y + c->frame->area.height - wb;
+ w = c->frame->area.width;
+ h = wb;
+
+ XMoveResizeWindow(ob_display, focus_indicator.bottom.win,
+ x, y, w, h);
+ a_focus_indicator->texture[0].data.lineart.x1 = 0;
+ a_focus_indicator->texture[0].data.lineart.y1 = 0;
+ a_focus_indicator->texture[0].data.lineart.x2 = 0;
+ a_focus_indicator->texture[0].data.lineart.y2 = h-1;
+ a_focus_indicator->texture[1].data.lineart.x1 = 0;
+ a_focus_indicator->texture[1].data.lineart.y1 = h-1;
+ a_focus_indicator->texture[1].data.lineart.x2 = w-1;
+ a_focus_indicator->texture[1].data.lineart.y2 = h-1;
+ a_focus_indicator->texture[2].data.lineart.x1 = w-1;
+ a_focus_indicator->texture[2].data.lineart.y1 = h-1;
+ a_focus_indicator->texture[2].data.lineart.x2 = w-1;
+ a_focus_indicator->texture[2].data.lineart.y2 = 0;
+ a_focus_indicator->texture[3].data.lineart.x1 = wl-1;
+ a_focus_indicator->texture[3].data.lineart.y1 = 0;
+ a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
+ a_focus_indicator->texture[3].data.lineart.y2 = 0;
+ RrPaint(a_focus_indicator, focus_indicator.bottom.win,
+ w, h);
+
+ XMapWindow(ob_display, focus_indicator.top.win);
+ XMapWindow(ob_display, focus_indicator.left.win);
+ XMapWindow(ob_display, focus_indicator.right.win);
+ XMapWindow(ob_display, focus_indicator.bottom.win);
+ }
+}
--- /dev/null
+/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
+
+ focus_cycle_popup.c for the Openbox window manager
+ Copyright (c) 2006 Mikael Magnusson
+ Copyright (c) 2003-2007 Dana Jansens
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ See the COPYING file for a copy of the GNU General Public License.
+*/
+
+#include "focus_cycle_popup.h"
+#include "popup.h"
+#include "client.h"
+#include "screen.h"
+#include "focus.h"
+#include "focus_cycle.h"
+#include "openbox.h"
+#include "window.h"
+#include "render/render.h"
+
+#include <X11/Xlib.h>
+#include <glib.h>
+
+#define ICON_SIZE 40
+#define ICON_HILITE_WIDTH 2
+#define ICON_HILITE_MARGIN 1
+#define OUTSIDE_BORDER 3
+
+typedef struct _ObFocusCyclePopup ObFocusCyclePopup;
+typedef struct _ObFocusCyclePopupTarget ObFocusCyclePopupTarget;
+
+struct _ObFocusCyclePopupTarget
+{
+ ObClient *client;
+ gchar *text;
+ Window win;
+};
+
+struct _ObFocusCyclePopup
+{
+ ObWindow obwin;
+ Window bg;
+
+ Window text;
+
+ GList *targets;
+ gint n_targets;
+
+ const ObFocusCyclePopupTarget *last_target;
+
+ gint maxtextw;
+
+ RrAppearance *a_bg;
+ RrAppearance *a_text;
+ RrAppearance *a_icon;
+
+ RrPixel32 *hilite_rgba;
+
+ 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,
+ gboolean desktop_windows);
+static void popup_render (ObFocusCyclePopup *p,
+ const ObClient *c);
+
+static Window create_window(Window parent, guint bwidth, gulong mask,
+ XSetWindowAttributes *attr)
+{
+ return XCreateWindow(ob_display, parent, 0, 0, 1, 1, bwidth,
+ RrDepth(ob_rr_inst), InputOutput,
+ RrVisual(ob_rr_inst), mask, attr);
+}
+
+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);
+ popup.a_icon = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
+
+ popup.a_text->surface.parent = popup.a_bg;
+ popup.a_icon->surface.parent = popup.a_bg;
+
+ popup.a_icon->texture[0].type = RR_TEXTURE_RGBA;
+
+ RrAppearanceAddTextures(popup.a_bg, 1);
+ popup.a_bg->texture[0].type = RR_TEXTURE_RGBA;
+
+ attrib.override_redirect = True;
+ attrib.border_pixel=RrColorPixel(ob_rr_theme->frame_focused_border_color);
+ popup.bg = create_window(RootWindow(ob_display, ob_screen),
+ ob_rr_theme->fbwidth,
+ CWOverrideRedirect | CWBorderPixel, &attrib);
+
+ popup.text = create_window(popup.bg, 0, 0, NULL);
+
+ popup.targets = NULL;
+ popup.n_targets = 0;
+ popup.last_target = NULL;
+
+ popup.hilite_rgba = NULL;
+
+ XMapWindow(ob_display, popup.text);
+
+ stacking_add(INTERNAL_AS_WINDOW(&popup));
+}
+
+void focus_cycle_popup_shutdown(gboolean reconfig)
+{
+ icon_popup_free(single_popup);
+
+ stacking_remove(INTERNAL_AS_WINDOW(&popup));
+
+ while(popup.targets) {
+ ObFocusCyclePopupTarget *t = popup.targets->data;
+
+ g_free(t->text);
+ XDestroyWindow(ob_display, t->win);
+
+ popup.targets = g_list_delete_link(popup.targets, popup.targets);
+ }
+
+ g_free(popup.hilite_rgba);
+
+ XDestroyWindow(ob_display, popup.text);
+ XDestroyWindow(ob_display, popup.bg);
+
+ RrAppearanceFree(popup.a_icon);
+ RrAppearanceFree(popup.a_text);
+ 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)
+{
+ gint maxwidth, n;
+ GList *it;
+
+ g_assert(p->targets == NULL);
+ g_assert(p->n_targets == 0);
+
+ /* make its width to be the width of all the possible titles */
+
+ /* build a list of all the valid focus targets and measure their strings,
+ and count them */
+ maxwidth = 0;
+ n = 0;
+ for (it = g_list_last(focus_order); it; it = g_list_previous(it)) {
+ ObClient *ft = it->data;
+
+ if (focus_cycle_target_valid(ft,
+ iconic_windows,
+ all_desktops,
+ dock_windows,
+ desktop_windows))
+ {
+ gchar *text = popup_get_name(ft);
+
+ /* 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);
+
+ 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;
+ }
+ }
+ }
+
+ p->n_targets = n;
+ p->maxtextw = maxwidth;
+}
+
+static gchar *popup_get_name(ObClient *c)
+{
+ ObClient *p;
+ gchar *title = NULL;
+ const gchar *desk = NULL;
+ gchar *ret;
+
+ /* find our highest direct parent, including non-normal windows */
+ for (p = c; p->transient_for && p->transient_for != OB_TRAN_GROUP;
+ p = p->transient_for);
+
+ if (c->desktop != DESKTOP_ALL && c->desktop != screen_desktop)
+ desk = screen_desktop_names[c->desktop];
+
+ /* use the transient's parent's title/icon if we don't have one */
+ if (p != c && !strcmp("", (c->iconic ? c->icon_title : c->title)))
+ title = g_strdup(p->iconic ? p->icon_title : p->title);
+
+ if (title == NULL)
+ title = g_strdup(c->iconic ? c->icon_title : c->title);
+
+ if (desk)
+ ret = g_strdup_printf("%s [%s]", title, desk);
+ else {
+ ret = title;
+ title = NULL;
+ }
+ g_free(title);
+
+ return ret;
+}
+
+static void popup_render(ObFocusCyclePopup *p, const ObClient *c)
+{
+ gint ml, mt, mr, mb;
+ gint l, t, r, b;
+ gint x, y, w, h;
+ Rect *screen_area;
+ gint icons_per_row;
+ gint icon_rows;
+ gint textx, texty, textw, texth;
+ gint rgbax, rgbay, rgbaw, rgbah;
+ gint icons_center_x;
+ gint innerw, innerh;
+ gint i;
+ GList *it;
+ const ObFocusCyclePopupTarget *newtarget;
+ gint newtargetx, newtargety;
+
+ /* XXX find the middle monitor? */
+ screen_area = screen_physical_area_monitor(0);
+
+ /* get the outside margins */
+ RrMargins(p->a_bg, &ml, &mt, &mr, &mb);
+
+ /* get our outside borders */
+ l = ml + OUTSIDE_BORDER;
+ r = mr + OUTSIDE_BORDER;
+ t = mt + OUTSIDE_BORDER;
+ b = mb + OUTSIDE_BORDER;
+
+ /* get the icon pictures' sizes */
+ innerw = ICON_SIZE - (ICON_HILITE_WIDTH + ICON_HILITE_MARGIN) * 2;
+ innerh = ICON_SIZE - (ICON_HILITE_WIDTH + ICON_HILITE_MARGIN) * 2;
+
+ /* get the width from the text and keep it within limits */
+ w = l + r + p->maxtextw;
+ w = MIN(w, MAX(screen_area->width/3, POPUP_WIDTH)); /* max width */
+ w = MAX(w, POPUP_WIDTH); /* min width */
+
+ /* how many icons will fit in that row? make the width fit that */
+ w -= l + r;
+ icons_per_row = (w + ICON_SIZE - 1) / ICON_SIZE;
+ w = icons_per_row * ICON_SIZE + l + r;
+
+ /* how many rows do we need? */
+ icon_rows = (p->n_targets-1) / icons_per_row + 1;
+
+ /* get the text dimensions */
+ textw = w - l - r;
+ texth = RrMinHeight(p->a_text);
+
+ /* find the height of the dialog */
+ h = t + b + (icon_rows * ICON_SIZE) + (OUTSIDE_BORDER*2 + texth);
+
+ /* get the position of the text */
+ textx = l;
+ texty = h - texth - b;
+
+ /* find the position for the popup (include the outer borders) */
+ x = screen_area->x + (screen_area->width -
+ (w + ob_rr_theme->fbwidth * 2)) / 2;
+ y = screen_area->y + (screen_area->height -
+ (h + ob_rr_theme->fbwidth * 2)) / 2;
+
+ /* get the dimensions of the target hilite texture */
+ rgbax = ml;
+ rgbay = mt;
+ 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->hilite_rgba = g_new(RrPixel32, rgbaw * rgbah);
+ p->a_bg->texture[0].data.rgba.data = p->hilite_rgba;
+
+ /* position the text, but don't draw it */
+ XMoveResizeWindow(ob_display, p->text, textx, texty, textw, texth);
+ p->a_text->surface.parentx = textx;
+ p->a_text->surface.parenty = texty;
+ }
+
+ /* find the focused target */
+ for (i = 0, it = p->targets; it; ++i, it = g_list_next(it)) {
+ const ObFocusCyclePopupTarget *target = it->data;
+ const gint row = i / icons_per_row; /* starting from 0 */
+ const gint col = i % icons_per_row; /* starting from 0 */
+
+ if (target->client == c) {
+ /* save the target */
+ newtarget = target;
+ newtargetx = icons_center_x + l + (col * ICON_SIZE);
+ newtargety = t + (row * ICON_SIZE);
+
+ if (!p->mapped)
+ break; /* if we're not dimensioning, then we're done */
+ }
+ }
+
+ g_assert(newtarget != NULL);
+
+ /* create the hilite under the target icon */
+ {
+ RrPixel32 color;
+ gint i, j, o;
+
+ color = ((ob_rr_theme->osd_color->r & 0xff) << RrDefaultRedOffset) +
+ ((ob_rr_theme->osd_color->g & 0xff) << RrDefaultGreenOffset) +
+ ((ob_rr_theme->osd_color->b & 0xff) << RrDefaultBlueOffset);
+
+ o = 0;
+ for (i = 0; i < rgbah; ++i)
+ for (j = 0; j < rgbaw; ++j) {
+ guchar a;
+ const gint x = j + rgbax - newtargetx;
+ const gint y = i + rgbay - newtargety;
+
+ if (x < 0 || x >= ICON_SIZE ||
+ y < 0 || y >= ICON_SIZE)
+ {
+ /* outside the target */
+ a = 0x00;
+ }
+ else if (x < ICON_HILITE_WIDTH ||
+ x >= ICON_SIZE - ICON_HILITE_WIDTH ||
+ y < ICON_HILITE_WIDTH ||
+ y >= ICON_SIZE - ICON_HILITE_WIDTH)
+ {
+ /* the border of the target */
+ a = 0x88;
+ }
+ else {
+ /* the background of the target */
+ a = 0x22;
+ }
+
+ p->hilite_rgba[o++] =
+ color + (a << RrDefaultAlphaOffset);
+ }
+ }
+
+ /* * * draw everything * * */
+
+ /* draw the background */
+ RrPaint(p->a_bg, p->bg, w, h);
+
+ /* draw the icons */
+ for (i = 0, it = p->targets; it; ++i, it = g_list_next(it)) {
+ const ObFocusCyclePopupTarget *target = it->data;
+
+ /* have to redraw the targetted icon and last targetted icon,
+ they can pick up the hilite changes in the backgroud */
+ if (!p->mapped || newtarget == target || p->last_target == target) {
+ const ObClientIcon *icon;
+ const gint row = i / icons_per_row; /* starting from 0 */
+ const gint col = i % icons_per_row; /* starting from 0 */
+ gint innerx, innery;
+
+ /* find the dimensions of the icon inside it */
+ 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;
+
+ /* move the icon */
+ XMoveResizeWindow(ob_display, target->win,
+ innerx, innery, innerw, innerh);
+
+ /* get the icon from the client */
+ 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.data = icon->data;
+
+ /* draw the icon */
+ p->a_icon->surface.parentx = innerx;
+ p->a_icon->surface.parenty = innery;
+ RrPaint(p->a_icon, target->win, innerw, innerh);
+ }
+ }
+
+ /* draw the text */
+ p->a_text->texture[0].data.text.string = newtarget->text;
+ p->a_text->surface.parentx = textx;
+ p->a_text->surface.parenty = texty;
+ RrPaint(p->a_text, p->text, textw, texth);
+
+ p->last_target = newtarget;
+}
+
+void focus_cycle_popup_show(ObClient *c, gboolean iconic_windows,
+ gboolean all_desktops, gboolean dock_windows,
+ gboolean desktop_windows)
+{
+ g_assert(c != NULL);
+
+ /* do this stuff only when the dialog is first showing */
+ if (!popup.mapped)
+ popup_setup(&popup, TRUE, iconic_windows, all_desktops,
+ dock_windows, desktop_windows);
+ g_assert(popup.targets != NULL);
+
+ popup_render(&popup, c);
+
+ if (!popup.mapped) {
+ /* show the dialog */
+ XMapWindow(ob_display, popup.bg);
+ XFlush(ob_display);
+ popup.mapped = TRUE;
+ }
+}
+
+void focus_cycle_popup_hide()
+{
+ XUnmapWindow(ob_display, popup.bg);
+ XFlush(ob_display);
+
+ popup.mapped = FALSE;
+
+ while(popup.targets) {
+ ObFocusCyclePopupTarget *t = popup.targets->data;
+
+ g_free(t->text);
+ XDestroyWindow(ob_display, t->win);
+
+ popup.targets = g_list_delete_link(popup.targets, popup.targets);
+ }
+ popup.n_targets = 0;
+ popup.last_target = NULL;
+
+ g_free(popup.hilite_rgba);
+ 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);
+}
#define FRAME_ANIMATE_ICONIFY_TIME 150000 /* .15 seconds */
#define FRAME_ANIMATE_ICONIFY_STEP_TIME (G_USEC_PER_SEC / 60) /* 60 Hz */
-#define FRAME_HANDLE_Y(f) (f->innersize.top + f->client->area.height + \
- f->cbwidth_y)
+#define FRAME_HANDLE_Y(f) (f->size.top + f->client->area.height + f->cbwidth_y)
static void flash_done(gpointer data);
static gboolean flash_timeout(gpointer data);
XWindowAttributes wattrib;
Status ret;
+ /* we're already running at 32 bit depth, yay. we don't need to use their
+ visual */
+ if (RrDepth(ob_rr_inst) == 32)
+ return NULL;
+
ret = XGetWindowAttributes(ob_display, c->window, &wattrib);
g_assert(ret != BadDrawable);
g_assert(ret != BadWindow);
XCreateColormap(ob_display,
RootWindow(ob_display, ob_screen),
visual, AllocNone);
- attrib.background_pixel = BlackPixel(ob_display, 0);
- attrib.border_pixel = BlackPixel(ob_display, 0);
+ attrib.background_pixel = BlackPixel(ob_display, ob_screen);
+ attrib.border_pixel = BlackPixel(ob_display, ob_screen);
}
attrib.event_mask = FRAME_EVENTMASK;
self->window = createWindow(RootWindow(ob_display, ob_screen), visual,
}
attrib.event_mask = ELEMENT_EVENTMASK;
self->title = createWindow(self->window, NULL, mask, &attrib);
+ self->titleleft = createWindow(self->window, NULL, mask, &attrib);
+ self->titletop = createWindow(self->window, NULL, mask, &attrib);
+ self->titletopleft = createWindow(self->window, NULL, mask, &attrib);
+ self->titletopright = createWindow(self->window, NULL, mask, &attrib);
+ self->titleright = createWindow(self->window, NULL, mask, &attrib);
+ self->titlebottom = createWindow(self->window, NULL, mask, &attrib);
- mask |= CWCursor;
- attrib.cursor = ob_cursor(OB_CURSOR_NORTH);
self->topresize = createWindow(self->title, NULL, mask, &attrib);
- attrib.cursor = ob_cursor(OB_CURSOR_NORTHWEST);
self->tltresize = createWindow(self->title, NULL, mask, &attrib);
self->tllresize = createWindow(self->title, NULL, mask, &attrib);
- attrib.cursor = ob_cursor(OB_CURSOR_NORTHEAST);
self->trtresize = createWindow(self->title, NULL, mask, &attrib);
self->trrresize = createWindow(self->title, NULL, mask, &attrib);
- attrib.cursor = ob_cursor(OB_CURSOR_WEST);
- self->leftresize = createWindow(self->inner, NULL, mask, &attrib);
- attrib.cursor = ob_cursor(OB_CURSOR_EAST);
- self->rightresize = createWindow(self->inner, NULL, mask, &attrib);
+ self->left = createWindow(self->window, NULL, mask, &attrib);
+ self->right = createWindow(self->window, NULL, mask, &attrib);
- mask &= ~CWCursor;
self->label = createWindow(self->title, NULL, mask, &attrib);
self->max = createWindow(self->title, NULL, mask, &attrib);
self->close = createWindow(self->title, NULL, mask, &attrib);
self->icon = createWindow(self->title, NULL, mask, &attrib);
self->iconify = createWindow(self->title, NULL, mask, &attrib);
- mask |= CWCursor;
- attrib.cursor = ob_cursor(OB_CURSOR_SOUTH);
self->handle = createWindow(self->window, NULL, mask, &attrib);
- attrib.cursor = ob_cursor(OB_CURSOR_SOUTHWEST);
self->lgrip = createWindow(self->handle, NULL, mask, &attrib);
- attrib.cursor = ob_cursor(OB_CURSOR_SOUTHEAST);
self->rgrip = createWindow(self->handle, NULL, mask, &attrib);
+ self->handleleft = createWindow(self->handle, NULL, mask, &attrib);
+ self->handleright = createWindow(self->handle, NULL, mask, &attrib);
+
+ self->handletop = createWindow(self->window, NULL, mask, &attrib);
+ self->handlebottom = createWindow(self->window, NULL, mask, &attrib);
+ self->lgripleft = createWindow(self->window, NULL, mask, &attrib);
+ self->lgriptop = createWindow(self->window, NULL, mask, &attrib);
+ self->lgripbottom = createWindow(self->window, NULL, mask, &attrib);
+ self->rgripright = createWindow(self->window, NULL, mask, &attrib);
+ self->rgriptop = createWindow(self->window, NULL, mask, &attrib);
+ self->rgripbottom = createWindow(self->window, NULL, mask, &attrib);
+
self->focused = FALSE;
/* the other stuff is shown based on decor settings */
XMapWindow(ob_display, self->plate);
XMapWindow(ob_display, self->inner);
- XMapWindow(ob_display, self->lgrip);
- XMapWindow(ob_display, self->rgrip);
XMapWindow(ob_display, self->label);
self->max_press = self->close_press = self->desk_press =
static void set_theme_statics(ObFrame *self)
{
- gint handle_height;
-
- if (ob_rr_theme->handle_height > 0)
- handle_height = ob_rr_theme->handle_height;
- else
- handle_height = 1;
-
-
/* set colors/appearance/sizes for stuff that doesn't change */
XResizeWindow(ob_display, self->max,
ob_rr_theme->button_size, ob_rr_theme->button_size);
ob_rr_theme->button_size, ob_rr_theme->button_size);
XResizeWindow(ob_display, self->shade,
ob_rr_theme->button_size, ob_rr_theme->button_size);
- XResizeWindow(ob_display, self->lgrip,
- ob_rr_theme->grip_width, handle_height);
- XResizeWindow(ob_display, self->rgrip,
- ob_rr_theme->grip_width, handle_height);
XResizeWindow(ob_display, self->tltresize,
ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
XResizeWindow(ob_display, self->trtresize,
if (!self->client->shaped) {
/* clear the shape on the frame window */
XShapeCombineMask(ob_display, self->window, ShapeBounding,
- self->innersize.left,
- self->innersize.top,
+ self->size.left,
+ self->size.top,
None, ShapeSet);
} else {
/* make the frame's shape match the clients */
XShapeCombineShape(ob_display, self->window, ShapeBounding,
- self->innersize.left,
- self->innersize.top,
+ self->size.left,
+ self->size.top,
self->client->window,
ShapeBounding, ShapeSet);
if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
xrect[0].x = -ob_rr_theme->fbwidth;
xrect[0].y = -ob_rr_theme->fbwidth;
- xrect[0].width = self->width + self->rbwidth * 2;
+ xrect[0].width = self->width + self->bwidth * 2;
xrect[0].height = ob_rr_theme->title_height +
self->bwidth * 2;
++num;
if (self->decorations & OB_FRAME_DECOR_HANDLE) {
xrect[1].x = -ob_rr_theme->fbwidth;
xrect[1].y = FRAME_HANDLE_Y(self);
- xrect[1].width = self->width + self->rbwidth * 2;
+ xrect[1].width = self->width + self->bwidth * 2;
xrect[1].height = ob_rr_theme->handle_height +
self->bwidth * 2;
++num;
self->bwidth = self->cbwidth_x = self->cbwidth_y = 0;
}
self->rbwidth = self->bwidth;
+ self->leftb = self->rightb = TRUE;
- if (self->max_horz)
- self->bwidth = self->cbwidth_x = 0;
+ if (self->max_horz) {
+ self->leftb = self->rightb = FALSE;
+ self->cbwidth_x = 0;
+ }
- STRUT_SET(self->innersize,
- self->cbwidth_x,
- self->cbwidth_y,
- self->cbwidth_x,
- self->cbwidth_y);
- self->width = self->client->area.width + self->cbwidth_x * 2 -
- (self->max_horz ? self->rbwidth * 2 : 0);
+ self->width = self->client->area.width + self->cbwidth_x * 2;
self->width = MAX(self->width, 1); /* no lower than 1 */
- /* set border widths */
- if (!fake) {
- XSetWindowBorderWidth(ob_display, self->window, self->bwidth);
- XSetWindowBorderWidth(ob_display, self->inner, self->bwidth);
- XSetWindowBorderWidth(ob_display, self->title, self->rbwidth);
- XSetWindowBorderWidth(ob_display, self->handle, self->rbwidth);
- XSetWindowBorderWidth(ob_display, self->lgrip, self->rbwidth);
- XSetWindowBorderWidth(ob_display, self->rgrip, self->rbwidth);
- XSetWindowBorderWidth(ob_display, self->leftresize, self->bwidth);
- XSetWindowBorderWidth(ob_display, self->rightresize, self->bwidth);
- }
+ STRUT_SET(self->size,
+ self->cbwidth_x + (self->leftb ? self->bwidth : 0),
+ self->cbwidth_y + self->bwidth,
+ self->cbwidth_x + (self->rightb ? self->bwidth : 0),
+ self->cbwidth_y + self->bwidth);
if (self->decorations & OB_FRAME_DECOR_TITLEBAR)
- self->innersize.top += ob_rr_theme->title_height + self->rbwidth +
- (self->rbwidth - self->bwidth);
+ self->size.top += ob_rr_theme->title_height + self->rbwidth;
if (self->decorations & OB_FRAME_DECOR_HANDLE &&
ob_rr_theme->handle_height > 0)
- self->innersize.bottom += ob_rr_theme->handle_height +
- self->rbwidth + (self->rbwidth - self->bwidth);
+ {
+ self->size.bottom += ob_rr_theme->handle_height + self->bwidth;
+ }
/* position/size and map/unmap all the windows */
if (!fake) {
+ if (self->bwidth) {
+ XMoveResizeWindow(ob_display, self->titletop,
+ ob_rr_theme->grip_width + self->bwidth, 0,
+ self->client->area.width +
+ self->cbwidth_x * 2 + self->bwidth * 2 -
+ (ob_rr_theme->grip_width + self->bwidth) * 2,
+ self->bwidth);
+ XMoveResizeWindow(ob_display, self->titletopleft,
+ 0, 0,
+ ob_rr_theme->grip_width + self->bwidth,
+ self->bwidth);
+ XMoveResizeWindow(ob_display, self->titletopright,
+ self->client->area.width +
+ self->cbwidth_x * 2 + self->bwidth * 2 -
+ ob_rr_theme->grip_width - self->bwidth,
+ 0,
+ ob_rr_theme->grip_width + self->bwidth,
+ self->bwidth);
+
+ XMoveResizeWindow(ob_display, self->titleleft,
+ 0, self->bwidth,
+ self->bwidth,
+ (self->leftb ?
+ ob_rr_theme->grip_width :
+ self->size.top - self->bwidth));
+ XMoveResizeWindow(ob_display, self->titleright,
+ self->client->area.width +
+ self->cbwidth_x * 2 + self->bwidth,
+ self->bwidth,
+ self->bwidth,
+ (self->rightb ?
+ ob_rr_theme->grip_width :
+ self->size.top - self->bwidth));
+
+ XMapWindow(ob_display, self->titletop);
+ XMapWindow(ob_display, self->titletopleft);
+ XMapWindow(ob_display, self->titletopright);
+ XMapWindow(ob_display, self->titleleft);
+ XMapWindow(ob_display, self->titleright);
+
+ if (self->decorations & OB_FRAME_DECOR_TITLEBAR &&
+ self->rbwidth)
+ {
+ XMoveResizeWindow(ob_display, self->titlebottom,
+ self->bwidth,
+ ob_rr_theme->title_height + self->bwidth,
+ self->client->area.width +
+ self->cbwidth_x * 2,
+ self->rbwidth);
+
+ XMapWindow(ob_display, self->titlebottom);
+ } else
+ XUnmapWindow(ob_display, self->titlebottom);
+ } else {
+ XUnmapWindow(ob_display, self->titletop);
+ XUnmapWindow(ob_display, self->titletopleft);
+ XUnmapWindow(ob_display, self->titletopright);
+ XUnmapWindow(ob_display, self->titleleft);
+ XUnmapWindow(ob_display, self->titleright);
+ }
+
if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
XMoveResizeWindow(ob_display, self->title,
- -self->bwidth, -self->bwidth,
+ self->bwidth, self->bwidth,
self->width, ob_rr_theme->title_height);
+
XMapWindow(ob_display, self->title);
if (self->decorations & OB_FRAME_DECOR_GRIPS) {
XMoveWindow(ob_display, self->trrresize,
self->width - ob_rr_theme->paddingx - 1, 0);
- XMoveResizeWindow(ob_display, self->leftresize,
- -(ob_rr_theme->fbwidth * 2) - 1,
- 0,
- 1,
- self->client->area.height +
- self->cbwidth_y * 2);
- XMoveResizeWindow(ob_display, self->rightresize,
- self->client->area.width +
- self->cbwidth_x * 2,
- 0,
- 1,
- self->client->area.height +
- self->cbwidth_y * 2);
-
XMapWindow(ob_display, self->topresize);
XMapWindow(ob_display, self->tltresize);
XMapWindow(ob_display, self->tllresize);
XMapWindow(ob_display, self->trtresize);
XMapWindow(ob_display, self->trrresize);
- XMapWindow(ob_display, self->leftresize);
- XMapWindow(ob_display, self->rightresize);
} else {
XUnmapWindow(ob_display, self->topresize);
XUnmapWindow(ob_display, self->tltresize);
XUnmapWindow(ob_display, self->tllresize);
XUnmapWindow(ob_display, self->trtresize);
XUnmapWindow(ob_display, self->trrresize);
- XUnmapWindow(ob_display, self->leftresize);
- XUnmapWindow(ob_display, self->rightresize);
}
} else
XUnmapWindow(ob_display, self->title);
layout_title(self);
if (!fake) {
- if (self->decorations & OB_FRAME_DECOR_HANDLE)
- {
- gint handle_height;
-
- if (ob_rr_theme->handle_height > 0)
- handle_height = ob_rr_theme->handle_height;
- else
- handle_height = 1;
+ if (self->bwidth) {
+ XMoveResizeWindow(ob_display, self->handlebottom,
+ ob_rr_theme->grip_width +
+ self->bwidth * 2,
+ self->size.top + self->client->area.height +
+ self->size.bottom - self->bwidth,
+ self->width - (ob_rr_theme->grip_width +
+ self->bwidth) * 2,
+ self->bwidth);
+
+ XMoveResizeWindow(ob_display, self->lgripleft,
+ 0,
+ self->size.top + self->client->area.height +
+ self->size.bottom -
+ (self->leftb ?
+ ob_rr_theme->grip_width :
+ self->size.bottom),
+ self->bwidth,
+ (self->leftb ?
+ ob_rr_theme->grip_width :
+ self->size.bottom));
+ XMoveResizeWindow(ob_display, self->rgripright,
+ self->size.left + self->client->area.width +
+ self->size.right - self->bwidth,
+ self->size.top + self->client->area.height +
+ self->size.bottom -
+ (self->leftb ?
+ ob_rr_theme->grip_width :
+ self->size.bottom),
+ self->bwidth,
+ (self->rightb ?
+ ob_rr_theme->grip_width :
+ self->size.bottom));
+
+ XMoveResizeWindow(ob_display, self->lgripbottom,
+ self->bwidth,
+ self->size.top + self->client->area.height +
+ self->size.bottom - self->bwidth,
+ ob_rr_theme->grip_width + self->bwidth,
+ self->bwidth);
+ XMoveResizeWindow(ob_display, self->rgripbottom,
+ self->size.left + self->client->area.width +
+ self->size.right - self->bwidth * 2 -
+ ob_rr_theme->grip_width,
+ self->size.top + self->client->area.height +
+ self->size.bottom - self->bwidth,
+ ob_rr_theme->grip_width + self->bwidth,
+ self->bwidth);
+
+ XMapWindow(ob_display, self->handlebottom);
+ XMapWindow(ob_display, self->lgripleft);
+ XMapWindow(ob_display, self->rgripright);
+ XMapWindow(ob_display, self->lgripbottom);
+ XMapWindow(ob_display, self->rgripbottom);
+
+ if (self->decorations & OB_FRAME_DECOR_HANDLE &&
+ ob_rr_theme->handle_height > 0)
+ {
+ XMoveResizeWindow(ob_display, self->handletop,
+ ob_rr_theme->grip_width +
+ self->bwidth * 2,
+ FRAME_HANDLE_Y(self),
+ self->width - (ob_rr_theme->grip_width +
+ self->bwidth) * 2,
+ self->bwidth);
+ XMapWindow(ob_display, self->handletop);
+
+ if (self->decorations & OB_FRAME_DECOR_GRIPS) {
+ XMoveResizeWindow(ob_display, self->handleleft,
+ ob_rr_theme->grip_width,
+ 0,
+ self->bwidth,
+ ob_rr_theme->handle_height);
+ XMoveResizeWindow(ob_display, self->handleright,
+ self->width -
+ ob_rr_theme->grip_width -
+ self->bwidth,
+ 0,
+ self->bwidth,
+ ob_rr_theme->handle_height);
+
+ XMoveResizeWindow(ob_display, self->lgriptop,
+ self->bwidth,
+ FRAME_HANDLE_Y(self),
+ ob_rr_theme->grip_width +
+ self->bwidth,
+ self->bwidth);
+ XMoveResizeWindow(ob_display, self->rgriptop,
+ self->size.left +
+ self->client->area.width +
+ self->size.right - self->bwidth * 2 -
+ ob_rr_theme->grip_width,
+ FRAME_HANDLE_Y(self),
+ ob_rr_theme->grip_width +
+ self->bwidth,
+ self->bwidth);
+
+ XMapWindow(ob_display, self->handleleft);
+ XMapWindow(ob_display, self->handleright);
+ XMapWindow(ob_display, self->lgriptop);
+ XMapWindow(ob_display, self->rgriptop);
+ } else {
+ XUnmapWindow(ob_display, self->handleleft);
+ XUnmapWindow(ob_display, self->handleright);
+ XUnmapWindow(ob_display, self->lgriptop);
+ XUnmapWindow(ob_display, self->rgriptop);
+ }
+ } else
+ XUnmapWindow(ob_display, self->handletop);
+ } else {
+ XUnmapWindow(ob_display, self->handlebottom);
+ XUnmapWindow(ob_display, self->lgripleft);
+ XUnmapWindow(ob_display, self->rgripright);
+ XUnmapWindow(ob_display, self->lgripbottom);
+ XUnmapWindow(ob_display, self->rgripbottom);
+ }
+ if (self->decorations & OB_FRAME_DECOR_HANDLE &&
+ ob_rr_theme->handle_height > 0)
+ {
XMoveResizeWindow(ob_display, self->handle,
- -self->bwidth, FRAME_HANDLE_Y(self),
- self->width, handle_height);
+ self->bwidth,
+ FRAME_HANDLE_Y(self) + self->bwidth,
+ self->width, ob_rr_theme->handle_height);
XMapWindow(ob_display, self->handle);
if (self->decorations & OB_FRAME_DECOR_GRIPS) {
- XMoveWindow(ob_display, self->lgrip,
- -self->rbwidth, -self->rbwidth);
- XMoveWindow(ob_display, self->rgrip,
- -self->rbwidth + self->width -
- ob_rr_theme->grip_width, -self->rbwidth);
+ XMoveResizeWindow(ob_display, self->lgrip,
+ 0, 0,
+ ob_rr_theme->grip_width,
+ ob_rr_theme->handle_height);
+ XMoveResizeWindow(ob_display, self->rgrip,
+ self->width - ob_rr_theme->grip_width,
+ 0,
+ ob_rr_theme->grip_width,
+ ob_rr_theme->handle_height);
+
XMapWindow(ob_display, self->lgrip);
XMapWindow(ob_display, self->rgrip);
} else {
} else
XUnmapWindow(ob_display, self->handle);
+ if (self->bwidth && !self->max_horz) {
+ XMoveResizeWindow(ob_display, self->left,
+ 0,
+ self->bwidth + ob_rr_theme->grip_width,
+ self->bwidth,
+ self->client->area.height +
+ self->size.top + self->size.bottom -
+ ob_rr_theme->grip_width * 2);
+ XMoveResizeWindow(ob_display, self->right,
+ self->client->area.width +
+ self->cbwidth_x * 2 + self->bwidth,
+ self->bwidth + ob_rr_theme->grip_width,
+ self->bwidth,
+ self->client->area.height +
+ self->size.top + self->size.bottom -
+ ob_rr_theme->grip_width * 2);
+
+ XMapWindow(ob_display, self->left);
+ XMapWindow(ob_display, self->right);
+ } else {
+ XUnmapWindow(ob_display, self->left);
+ XUnmapWindow(ob_display, self->right);
+ }
+
/* move and resize the inner border window which contains the plate
*/
XMoveResizeWindow(ob_display, self->inner,
- self->innersize.left - self->cbwidth_x -
- self->bwidth,
- self->innersize.top - self->cbwidth_y -
- self->bwidth,
+ 0,
+ self->size.top - self->cbwidth_y,
self->client->area.width +
- self->cbwidth_x * 2,
+ self->cbwidth_x * 2 +
+ (self->leftb ? self->bwidth : 0) +
+ (self->rightb ? self->bwidth : 0),
self->client->area.height +
self->cbwidth_y * 2);
/* move the plate */
XMoveWindow(ob_display, self->plate,
- self->cbwidth_x, self->cbwidth_y);
+ (self->leftb ? self->bwidth : 0) + self->cbwidth_x,
+ self->cbwidth_y);
/* when the client has StaticGravity, it likes to move around. */
XMoveWindow(ob_display, self->client->window, 0, 0);
}
-
- STRUT_SET(self->size,
- self->innersize.left + self->bwidth,
- self->innersize.top + self->bwidth,
- self->innersize.right + self->bwidth,
- self->innersize.bottom + self->bwidth);
}
/* shading can change without being moved or resized */
self->client->area.width +
self->size.left + self->size.right,
(self->client->shaded ?
- ob_rr_theme->title_height + self->rbwidth * 2:
+ ob_rr_theme->title_height + self->bwidth * 2:
self->client->area.height +
self->size.top + self->size.bottom));
reflected afterwards.
*/
XMoveResizeWindow(ob_display, self->window,
- self->area.x, self->area.y,
- self->area.width - self->bwidth * 2,
- self->area.height - self->bwidth * 2);
+ self->area.x,
+ self->area.y,
+ self->area.width,
+ self->area.height);
if (resized) {
framerender_frame(self);
if (resized && (self->decorations & OB_FRAME_DECOR_TITLEBAR))
XResizeWindow(ob_display, self->label, self->label_width,
ob_rr_theme->label_height);
+
+ /* set up cursors */
+ if (!fake &&
+ (self->functions & OB_CLIENT_FUNC_RESIZE) !=
+ (self->client->functions & OB_CLIENT_FUNC_RESIZE))
+ {
+ gboolean r = self->client->functions & OB_CLIENT_FUNC_RESIZE;
+ XSetWindowAttributes a;
+
+ a.cursor = ob_cursor(r ? OB_CURSOR_NORTH : OB_CURSOR_NONE);
+ XChangeWindowAttributes(ob_display, self->topresize, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->titletop, CWCursor, &a);
+ a.cursor = ob_cursor(r ? OB_CURSOR_NORTHWEST : OB_CURSOR_NONE);
+ XChangeWindowAttributes(ob_display, self->tltresize, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->tllresize, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->titletopleft, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->titleleft, CWCursor, &a);
+ a.cursor = ob_cursor(r ? OB_CURSOR_NORTHEAST : OB_CURSOR_NONE);
+ XChangeWindowAttributes(ob_display, self->trtresize, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->trrresize, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->titletopright, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->titleright, CWCursor, &a);
+ a.cursor = ob_cursor(r ? OB_CURSOR_WEST : OB_CURSOR_NONE);
+ XChangeWindowAttributes(ob_display, self->left, CWCursor, &a);
+ a.cursor = ob_cursor(r ? OB_CURSOR_EAST : OB_CURSOR_NONE);
+ XChangeWindowAttributes(ob_display, self->right, CWCursor, &a);
+ a.cursor = ob_cursor(r ? OB_CURSOR_SOUTH : OB_CURSOR_NONE);
+ XChangeWindowAttributes(ob_display, self->handle, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->handletop, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->handlebottom, CWCursor, &a);
+ a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHWEST : OB_CURSOR_NONE);
+ XChangeWindowAttributes(ob_display, self->lgrip, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->handleleft, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->lgripleft, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->lgriptop, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->lgripbottom, CWCursor, &a);
+ a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHEAST : OB_CURSOR_NONE);
+ XChangeWindowAttributes(ob_display, self->rgrip, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->handleright, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->rgripright, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->rgriptop, CWCursor, &a);
+ XChangeWindowAttributes(ob_display, self->rgripbottom, CWCursor, &a);
+
+ self->functions = self->client->functions;
+ }
}
void frame_adjust_client_area(ObFrame *self)
g_hash_table_insert(window_map, &self->tllresize, self->client);
g_hash_table_insert(window_map, &self->trtresize, self->client);
g_hash_table_insert(window_map, &self->trrresize, self->client);
- g_hash_table_insert(window_map, &self->leftresize, self->client);
- g_hash_table_insert(window_map, &self->rightresize, self->client);
+ g_hash_table_insert(window_map, &self->left, self->client);
+ g_hash_table_insert(window_map, &self->right, self->client);
+ g_hash_table_insert(window_map, &self->titleleft, self->client);
+ g_hash_table_insert(window_map, &self->titletop, self->client);
+ g_hash_table_insert(window_map, &self->titletopleft, self->client);
+ g_hash_table_insert(window_map, &self->titletopright, self->client);
+ g_hash_table_insert(window_map, &self->titleright, self->client);
+ g_hash_table_insert(window_map, &self->titlebottom, self->client);
+ g_hash_table_insert(window_map, &self->handleleft, self->client);
+ g_hash_table_insert(window_map, &self->handletop, self->client);
+ g_hash_table_insert(window_map, &self->handleright, self->client);
+ g_hash_table_insert(window_map, &self->handlebottom, self->client);
+ g_hash_table_insert(window_map, &self->lgripleft, self->client);
+ g_hash_table_insert(window_map, &self->lgriptop, self->client);
+ g_hash_table_insert(window_map, &self->lgripbottom, self->client);
+ g_hash_table_insert(window_map, &self->rgripright, self->client);
+ g_hash_table_insert(window_map, &self->rgriptop, self->client);
+ g_hash_table_insert(window_map, &self->rgripbottom, self->client);
}
void frame_release_client(ObFrame *self)
g_hash_table_remove(window_map, &self->tllresize);
g_hash_table_remove(window_map, &self->trtresize);
g_hash_table_remove(window_map, &self->trrresize);
- g_hash_table_remove(window_map, &self->leftresize);
- g_hash_table_remove(window_map, &self->rightresize);
+ g_hash_table_remove(window_map, &self->left);
+ g_hash_table_remove(window_map, &self->right);
+ g_hash_table_remove(window_map, &self->titleleft);
+ g_hash_table_remove(window_map, &self->titletop);
+ g_hash_table_remove(window_map, &self->titletopleft);
+ g_hash_table_remove(window_map, &self->titletopright);
+ g_hash_table_remove(window_map, &self->titleright);
+ g_hash_table_remove(window_map, &self->titlebottom);
+ g_hash_table_remove(window_map, &self->handleleft);
+ g_hash_table_remove(window_map, &self->handletop);
+ g_hash_table_remove(window_map, &self->handleright);
+ g_hash_table_remove(window_map, &self->handlebottom);
+ g_hash_table_remove(window_map, &self->lgripleft);
+ g_hash_table_remove(window_map, &self->lgriptop);
+ g_hash_table_remove(window_map, &self->lgripbottom);
+ g_hash_table_remove(window_map, &self->rgripright);
+ g_hash_table_remove(window_map, &self->rgriptop);
+ g_hash_table_remove(window_map, &self->rgripbottom);
ob_main_loop_timeout_remove_data(ob_main_loop, flash_timeout, self, TRUE);
}
return OB_FRAME_CONTEXT_TITLEBAR;
}
- if (win == self->window) return OB_FRAME_CONTEXT_FRAME;
- if (win == self->label) return OB_FRAME_CONTEXT_TITLEBAR;
- if (win == self->handle) return OB_FRAME_CONTEXT_BOTTOM;
- if (win == self->lgrip) return OB_FRAME_CONTEXT_BLCORNER;
- if (win == self->rgrip) return OB_FRAME_CONTEXT_BRCORNER;
- if (win == self->topresize) return OB_FRAME_CONTEXT_TOP;
- if (win == self->tltresize) return OB_FRAME_CONTEXT_TLCORNER;
- if (win == self->tllresize) return OB_FRAME_CONTEXT_TLCORNER;
- if (win == self->trtresize) return OB_FRAME_CONTEXT_TRCORNER;
- if (win == self->trrresize) return OB_FRAME_CONTEXT_TRCORNER;
- if (win == self->leftresize) return OB_FRAME_CONTEXT_LEFT;
- if (win == self->rightresize) return OB_FRAME_CONTEXT_RIGHT;
- if (win == self->max) return OB_FRAME_CONTEXT_MAXIMIZE;
- if (win == self->iconify) return OB_FRAME_CONTEXT_ICONIFY;
- if (win == self->close) return OB_FRAME_CONTEXT_CLOSE;
- if (win == self->icon) return OB_FRAME_CONTEXT_ICON;
- if (win == self->desk) return OB_FRAME_CONTEXT_ALLDESKTOPS;
- if (win == self->shade) return OB_FRAME_CONTEXT_SHADE;
+ if (win == self->window) return OB_FRAME_CONTEXT_FRAME;
+ if (win == self->label) return OB_FRAME_CONTEXT_TITLEBAR;
+ if (win == self->handle) return OB_FRAME_CONTEXT_BOTTOM;
+ if (win == self->handletop) return OB_FRAME_CONTEXT_BOTTOM;
+ if (win == self->handlebottom) return OB_FRAME_CONTEXT_BOTTOM;
+ if (win == self->handleleft) return OB_FRAME_CONTEXT_BLCORNER;
+ if (win == self->lgrip) return OB_FRAME_CONTEXT_BLCORNER;
+ if (win == self->lgripleft) return OB_FRAME_CONTEXT_BLCORNER;
+ if (win == self->lgriptop) return OB_FRAME_CONTEXT_BLCORNER;
+ if (win == self->lgripbottom) return OB_FRAME_CONTEXT_BLCORNER;
+ if (win == self->handleright) return OB_FRAME_CONTEXT_BRCORNER;
+ if (win == self->rgrip) return OB_FRAME_CONTEXT_BRCORNER;
+ if (win == self->rgripright) return OB_FRAME_CONTEXT_BLCORNER;
+ if (win == self->rgriptop) return OB_FRAME_CONTEXT_BLCORNER;
+ if (win == self->rgripbottom) return OB_FRAME_CONTEXT_BLCORNER;
+ if (win == self->titletop) return OB_FRAME_CONTEXT_TOP;
+ if (win == self->topresize) return OB_FRAME_CONTEXT_TOP;
+ if (win == self->tltresize) return OB_FRAME_CONTEXT_TLCORNER;
+ if (win == self->tllresize) return OB_FRAME_CONTEXT_TLCORNER;
+ if (win == self->titleleft) return OB_FRAME_CONTEXT_TLCORNER;
+ if (win == self->titletopleft) return OB_FRAME_CONTEXT_TLCORNER;
+ if (win == self->trtresize) return OB_FRAME_CONTEXT_TRCORNER;
+ if (win == self->trrresize) return OB_FRAME_CONTEXT_TRCORNER;
+ if (win == self->titleright) return OB_FRAME_CONTEXT_TRCORNER;
+ if (win == self->titletopright) return OB_FRAME_CONTEXT_TRCORNER;
+ if (win == self->left) return OB_FRAME_CONTEXT_LEFT;
+ if (win == self->right) return OB_FRAME_CONTEXT_RIGHT;
+ if (win == self->max) return OB_FRAME_CONTEXT_MAXIMIZE;
+ if (win == self->iconify) return OB_FRAME_CONTEXT_ICONIFY;
+ if (win == self->close) return OB_FRAME_CONTEXT_CLOSE;
+ if (win == self->icon) return OB_FRAME_CONTEXT_ICON;
+ if (win == self->desk) return OB_FRAME_CONTEXT_ALLDESKTOPS;
+ if (win == self->shade) return OB_FRAME_CONTEXT_SHADE;
return OB_FRAME_CONTEXT_NONE;
}
x = iconx;
y = icony;
w = iconw;
- h = self->innersize.top; /* just the titlebar */
+ h = self->size.top; /* just the titlebar */
}
if (time > 0) {
x = x - (dx * elapsed) / FRAME_ANIMATE_ICONIFY_TIME;
y = y - (dy * elapsed) / FRAME_ANIMATE_ICONIFY_TIME;
w = w - (dw * elapsed) / FRAME_ANIMATE_ICONIFY_TIME;
- h = self->innersize.top; /* just the titlebar */
+ h = self->size.top; /* just the titlebar */
}
if (time == 0)