tColor borders according to the window content (pixel color) - glazier - window management experiments
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
(DIR) commit 150c2a4e6e0e3e69da4e7c2d3601a84a052222b5
(DIR) parent c6e64b8528cc5f40abc0d12d7373fd3c13a5cf12
(HTM) Author: Willy Goiffon <dev@z3bra.org>
Date: Mon, 22 Jun 2020 09:58:12 +0200
Color borders according to the window content (pixel color)
Upon coloring an unfocused window, the color of all 4 corners will be
retrieved and used to paint the window border.
The focused window will get a hardcoded color defined in config.h
Diffstat:
M config.mk | 2 +-
M glazier.c | 55 +++++++++++++++++++++++++++----
2 files changed, 50 insertions(+), 7 deletions(-)
---
(DIR) diff --git a/config.mk b/config.mk
t@@ -7,4 +7,4 @@ MANDIR = ${PREFIX}/man
CPPFLAGS = -I./libwm
CFLAGS = -Wall -Wextra -pedantic -g
LDFLAGS = -L./libwm ${LIBS}
-LIBS = -lxcb -lxcb-cursor -lxcb-randr -lwm
+LIBS = -lxcb -lxcb-cursor -lxcb-image -lxcb-randr -lwm
(DIR) diff --git a/glazier.c b/glazier.c
t@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <xcb/xcb.h>
#include <xcb/xcb_cursor.h>
+#include <xcb/xcb_image.h>
#include <xcb/randr.h>
#include "arg.h"
t@@ -41,6 +42,8 @@ enum {
void usage(char *);
static int takeover();
static int adopt(xcb_window_t);
+static uint32_t backpixel(xcb_window_t);
+static int paint(xcb_window_t);
static int inflate(xcb_window_t, int);
static int outline(xcb_drawable_t, int, int, int, int);
static int ev_callback(xcb_generic_event_t *);
t@@ -139,6 +142,46 @@ adopt(xcb_window_t wid)
| XCB_EVENT_MASK_STRUCTURE_NOTIFY);
}
+uint32_t
+backpixel(xcb_window_t wid)
+{
+ int w, h;
+ uint32_t color;
+ xcb_image_t *px;
+
+ w = wm_get_attribute(wid, ATTR_W);
+ h = wm_get_attribute(wid, ATTR_H);
+
+ px = xcb_image_get(conn, wid, 0, 0, 1, 1, 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP);
+ if (px) color = xcb_image_get_pixel(px, 0, 0);
+
+ if (!color) {
+ px = xcb_image_get(conn, wid, w - 1, 0, 1, 1, 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP);
+ if (px) color = xcb_image_get_pixel(px, 0, 0);
+ }
+
+ if (!color) {
+ px = xcb_image_get(conn, wid, 0, h - 1, 1, 1, 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP);
+ if (px) color = xcb_image_get_pixel(px, 0, 0);
+ }
+
+ if (!color) {
+ px = xcb_image_get(conn, wid, w, h, 1, 1, 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP);
+ if (px) color = xcb_image_get_pixel(px, 0, 0);
+ }
+
+ return color ? color : border_color;
+}
+
+int
+paint(xcb_window_t wid)
+{
+ if (wid == wm_get_focus())
+ return wm_set_border(border, border_color_active, wid);
+
+ return wm_set_border(border, backpixel(wid), wid);
+}
+
/*
* Inflating a window will grow it both vertically and horizontally in
* all 4 directions, thus making it look like it is inflating.
t@@ -181,12 +224,12 @@ takeover()
adopt(wid);
if (wm_is_mapped(wid))
- wm_set_border(border, border_color, wid);
+ paint(wid);
}
wid = wm_get_focus();
if (wid != scrn->root)
- wm_set_border(border, border_color_active, wid);
+ paint(wid);
return n;
}
t@@ -313,7 +356,7 @@ cb_mapreq(xcb_generic_event_t *ev)
fprintf(stderr, "%s 0x%08x\n", XEV(e), e->window);
wm_remap(e->window, MAP);
- wm_set_border(border, border_color, e->window);
+ paint(e->window);
wm_set_focus(e->window);
/* prevent window to pop outside the screen */
t@@ -460,7 +503,7 @@ cb_mouse_release(xcb_generic_event_t *ev)
w = wm_get_attribute(curwid, ATTR_W);
h = wm_get_attribute(curwid, ATTR_H);
xcb_clear_area(conn, 1, curwid, 0, 0, w, h);
- wm_set_border(-1, border_color_active, curwid);
+ paint(curwid);
return 0;
}
t@@ -574,10 +617,10 @@ cb_focus(xcb_generic_event_t *ev)
switch(e->response_type & ~0x80) {
case XCB_FOCUS_IN:
curwid = e->event;
- return wm_set_border(-1, border_color_active, e->event);
+ return paint(e->event);
break; /* NOTREACHED */
case XCB_FOCUS_OUT:
- return wm_set_border(-1, border_color, e->event);
+ return paint(e->event);
break; /* NOTREACHED */
}