[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] New setting: window_inner_border_width



Hi,

The first patch is a generalization of set_window_double_border, the
other one provides a window_inner_border_width setting.

Greetings,
-- 
 b.d
(| |)
 ^ ^
>From 59b847807f392c5c01d3bf82897d93e7abbbe9d6 Mon Sep 17 00:00:00 2001
From: Bastien Dejean <nihilhill _at_ gmail _dot_ com>
Date: Mon, 23 Jul 2012 21:52:58 +0200
Subject: [PATCH 1/2] Generalization of set_window_double_border

---
 src/clientlist.c |  6 ++---
 src/utils.c      | 71 ++++++++++++++++++++++++++++++++++++++------------------
 src/utils.h      |  5 ++--
 3 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/src/clientlist.c b/src/clientlist.c
index c6abd81..589d2ae 100644
--- a/src/clientlist.c
+++ b/src/clientlist.c
@@ -369,7 +369,7 @@ void client_resize(HSClient* client, XRectangle rect, HSFrame* frame) {
     if (*g_double_window_border) {
         unsigned long current_border_color = get_window_border_color(client);
         HSDebug("client_resize %s\n", current_border_color == g_window_border_active_color ? "ACTIVE" : "NORMAL");
-        set_window_double_border(win, g_window_border_inner_color, current_border_color);
+        set_window_double_border(g_display, win, 1, g_window_border_inner_color, current_border_color);
     }
     //// send new size to client
     //// WHY SHOULD I? -> faster? only one call?
@@ -432,7 +432,7 @@ void client_resize_floating(HSClient* client, HSMonitor* m) {
     if (*g_double_window_border) {
         unsigned long current_border_color = get_window_border_color(client);
         HSDebug("client_resize %s\n", current_border_color == g_window_border_active_color ? "ACTIVE" : "NORMAL");
-        set_window_double_border(client->window, g_window_border_inner_color, current_border_color);
+        set_window_double_border(g_display, client->window, 1, g_window_border_inner_color, current_border_color);
     }
 }
 
@@ -622,7 +622,7 @@ int client_set_property_command(int argc, char** argv) {
 
 void window_update_border(Window window, unsigned long color) {
     if (*g_double_window_border) {
-        set_window_double_border(window, g_window_border_inner_color, color);
+        set_window_double_border(g_display, window, 1, g_window_border_inner_color, color);
     } else {
         XSetWindowBorder(g_display, window, color);
     }
diff --git a/src/utils.c b/src/utils.c
index f71dcbb..4860425 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -304,15 +304,18 @@ void* table_find(void* start, size_t elem_size, size_t count,
     return NULL;
 }
 
-void set_window_double_border(Window win, unsigned long inner_border_color, unsigned long outer_border_color) {
+/**
+ * \brief   emulates a double window border through the border pixmap mechanism
+ */
+void set_window_double_border(Display *dpy, Window win, int ibw, unsigned long inner_color, unsigned long outer_color) {
     XWindowAttributes wa;
 
-    if (!XGetWindowAttributes(g_display, win, &wa))
+    if (!XGetWindowAttributes(dpy, win, &wa))
         return;
 
-    int border_width = wa.border_width;
+    int bw = wa.border_width;
 
-    if (border_width < 2)
+    if (bw < 2 || ibw >= bw || ibw < 1)
         return;
 
     HSDebug("set_window_double_border %ix%i+%i+%i\n", wa.width, wa.height, wa.x, wa.y);
@@ -320,26 +323,48 @@ void set_window_double_border(Window win, unsigned long inner_border_color, unsi
     int width = wa.width;
     int height = wa.height;
 
-    unsigned int depth = DefaultDepth(g_display, DefaultScreen(g_display));
-
-    int full_width = width + 2 * border_width;
-    int full_height = height + 2 * border_width;
-
-    XSegment segments[4] =
+    unsigned int depth = DefaultDepth(dpy, DefaultScreen(dpy));
+
+    int full_width = width + 2 * bw;
+    int full_height = height + 2 * bw;
+
+    // the inner border is represented through the following pattern:
+    //
+    //                           ââ  ââ
+    //                           ââ  ââ
+    //                           ââ  ââ
+    //                           ââ  ââ
+    //                           ââ  ââ
+    //                           ââ  ââ
+    //                           ââ  ââ
+    //                           ââ  ââ
+    //                           ââ  ââ
+    //                           ââ  ââ
+    //                           ââ  ââ
+    //   ââââââââââââââââââââââââââ  ââ
+    //
+    //   ââââââââââââââââââââââââââ  ââ
+
+    XRectangle rectangles[] =
     {
-        { width, 0, width, height },
-        { full_width - 1, 0, full_width - 1, height },
-        { 0, height, width, height },
-        { 0, full_height - 1, width, full_height - 1 }
+        { width, 0, ibw, height + ibw },
+        { full_width - ibw, 0, ibw, height + ibw },
+        { 0, height, width + ibw, ibw },
+        { 0, full_height - ibw, width + ibw, ibw },
+        { full_width - ibw, full_height - ibw, ibw, ibw }
     };
 
-    Pixmap pix = XCreatePixmap(g_display, g_root, full_width, full_height, depth);
-    GC gc = XCreateGC(g_display, pix, 0, NULL);
-    XSetForeground(g_display, gc, outer_border_color);
-    XFillRectangle(g_display, pix, gc, 0, 0, full_width, full_height);
-    XSetForeground(g_display, gc, inner_border_color);
-    XDrawSegments(g_display, pix, gc, segments, 4);
-    XDrawPoint(g_display, pix, gc, full_width - 1, full_height - 1);
-    XSetWindowBorderPixmap(g_display, win, pix);
-    XFreePixmap(g_display, pix);
+    Pixmap pix = XCreatePixmap(dpy, g_root, full_width, full_height, depth);
+    GC gc = XCreateGC(dpy, pix, 0, NULL);
+
+    /* outer border */
+    XSetForeground(dpy, gc, outer_color);
+    XFillRectangle(dpy, pix, gc, 0, 0, full_width, full_height);
+
+    /* inner border */
+    XSetForeground(dpy, gc, inner_color);
+    XFillRectangles(dpy, pix, gc, rectangles, LENGTH(rectangles));
+
+    XSetWindowBorderPixmap(dpy, win, pix);
+    XFreePixmap(dpy, pix);
 }
diff --git a/src/utils.h b/src/utils.h
index cbff41b..1f2926c 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -64,9 +64,8 @@ bool memberequals_int(void* pmember, void* needle);
 void* table_find(void* start, size_t elem_size, size_t count,
                  size_t member_offset, MemberEquals equals, void* needle);
 
-void set_window_double_border(Window win,
-                              unsigned long inner_border_color,
-                              unsigned long outer_border_color);
+void set_window_double_border(Display *dpy, Window win, int ibw,
+                              unsigned long inner_color, unsigned long outer_color);
 
 #define STATIC_TABLE_FIND(TYPE, TABLE, MEMBER, EQUALS, NEEDLE)  \
     ((TYPE*) table_find((TABLE),                                \
-- 
1.7.11.3

>From 17122fbb51191c45208d64ad3fba3b7796c7fde3 Mon Sep 17 00:00:00 2001
From: Bastien Dejean <nihilhill _at_ gmail _dot_ com>
Date: Mon, 23 Jul 2012 22:30:27 +0200
Subject: [PATCH 2/2] New setting: window_inner_border_width

---
 NEWS                 |  1 +
 doc/herbstluftwm.txt |  5 ++++-
 src/clientlist.c     | 17 +++++++++++------
 src/settings.c       |  1 +
 4 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/NEWS b/NEWS
index dac2d5d..0d639dd 100644
--- a/NEWS
+++ b/NEWS
@@ -29,6 +29,7 @@ Changes:
     * new settings: smart_frame_surroundings and smart_window_surroundings
     * new setting: double_window_border
     * new setting: window_border_inner_color
+    * new setting: window_inner_border_width
     * new option --skip-invisible for cycle_all
 
 Release 0.3 on 2012-04-12
diff --git a/doc/herbstluftwm.txt b/doc/herbstluftwm.txt
index 9f59dd8..f88bce2 100644
--- a/doc/herbstluftwm.txt
+++ b/doc/herbstluftwm.txt
@@ -580,6 +580,9 @@ raise_on_click (Integer)::
 window_border_width (Integer)::
     Border width of a window.
 
+window_inner_border_width (Integer)::
+    Width of the inner border of a window.
+
 window_border_active_color (String/Color)::
     Border color of a focused window.
 
@@ -634,7 +637,7 @@ double_window_border (Integer)::
     If set, one pixel inner window borders will be drawn in addition to the
     regular window borders. It will only activate if window_border_width is
     greater than one. The inner border's color can be set via
-    window_border_inner_color.
+    window_border_inner_color and its width via window_inner_border_width.
 
 focus_follows_shift (Integer)::
     If set, focus stays in the window, if window is shifted to another frame.
diff --git a/src/clientlist.c b/src/clientlist.c
index 589d2ae..f17daf2 100644
--- a/src/clientlist.c
+++ b/src/clientlist.c
@@ -31,6 +31,7 @@
 int g_monitor_float_treshold = 24;
 
 int* g_window_border_width;
+int* g_window_inner_border_width;
 int* g_raise_on_focus;
 int* g_snap_gap;
 int* g_smart_window_surroundings;
@@ -60,6 +61,7 @@ static HSClient* create_client() {
 
 static void fetch_colors() {
     g_window_border_width = &(settings_find("window_border_width")->value.i);
+    g_window_inner_border_width = &(settings_find("window_inner_border_width")->value.i);
     g_window_gap = &(settings_find("window_gap")->value.i);
     g_snap_gap = &(settings_find("snap_gap")->value.i);
     g_smart_window_surroundings = &(settings_find("smart_window_surroundings")->value.i);
@@ -366,10 +368,11 @@ void client_resize(HSClient* client, XRectangle rect, HSFrame* frame) {
 
     XSetWindowBorderWidth(g_display, win, border_width);
     XMoveResizeWindow(g_display, win, rect.x, rect.y, rect.width, rect.height);
-    if (*g_double_window_border) {
+    if (*g_double_window_border && *g_window_inner_border_width > 0
+        && *g_window_inner_border_width < *g_window_border_width) {
         unsigned long current_border_color = get_window_border_color(client);
         HSDebug("client_resize %s\n", current_border_color == g_window_border_active_color ? "ACTIVE" : "NORMAL");
-        set_window_double_border(g_display, win, 1, g_window_border_inner_color, current_border_color);
+        set_window_double_border(g_display, win, *g_window_inner_border_width, g_window_border_inner_color, current_border_color);
     }
     //// send new size to client
     //// WHY SHOULD I? -> faster? only one call?
@@ -429,10 +432,11 @@ void client_resize_floating(HSClient* client, HSMonitor* m) {
     XSetWindowBorderWidth(g_display, client->window, *g_window_border_width);
     XMoveResizeWindow(g_display, client->window,
         rect.x, rect.y, rect.width, rect.height);
-    if (*g_double_window_border) {
+    if (*g_double_window_border && *g_window_inner_border_width > 0
+        && *g_window_inner_border_width < *g_window_border_width) {
         unsigned long current_border_color = get_window_border_color(client);
         HSDebug("client_resize %s\n", current_border_color == g_window_border_active_color ? "ACTIVE" : "NORMAL");
-        set_window_double_border(g_display, client->window, 1, g_window_border_inner_color, current_border_color);
+        set_window_double_border(g_display, client->window, *g_window_inner_border_width, g_window_border_inner_color, current_border_color);
     }
 }
 
@@ -621,8 +625,9 @@ int client_set_property_command(int argc, char** argv) {
 }
 
 void window_update_border(Window window, unsigned long color) {
-    if (*g_double_window_border) {
-        set_window_double_border(g_display, window, 1, g_window_border_inner_color, color);
+    if (*g_double_window_border && *g_window_inner_border_width > 0
+        && *g_window_inner_border_width < *g_window_border_width) {
+        set_window_double_border(g_display, window, *g_window_inner_border_width, g_window_border_inner_color, color);
     } else {
         XSetWindowBorder(g_display, window, color);
     }
diff --git a/src/settings.c b/src/settings.c
index 654f4e0..9d3ba04 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -49,6 +49,7 @@ SettingsPair g_settings[] = {
     SET_INT(    "frame_active_opacity",            100,         FR_COLORS   ),
     SET_INT(    "frame_normal_opacity",            100,         FR_COLORS   ),
     SET_INT(    "window_border_width",             2,           CL_COLORS   ),
+    SET_INT(    "window_inner_border_width",       1,           CL_COLORS   ),
     SET_STRING( "window_border_active_color",      "red",       CL_COLORS   ),
     SET_STRING( "window_border_normal_color",      "blue",      CL_COLORS   ),
     SET_STRING( "window_border_urgent_color",      "orange",    CL_COLORS   ),
-- 
1.7.11.3

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/