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

Re: [PATCH] New setting: window_inner_border_width



Thorsten WiÃmann:

> On Mon, Jul 23, 2012 at 10:40:00PM +0200, Bastien Dejean wrote:
> > The first patch is a generalization of set_window_double_border, the
> > other one provides a window_inner_border_width setting.
> 
> Actually the double_window_border setting is obsolete if theres a
> window_border_inner_width setting (where window_inner_border_width = 0
> means, the double border is disabled).

I fixed the second patch and followed your naming conventions.

The first patch is unchanged.

Cheers,
-- 
 b.d
(| |)
 ^ ^
>From 3280051f17431fd2f88668fee9c7a71950794b17 Mon Sep 17 00:00:00 2001
From: Bastien Dejean <nihilhill _at_ gmail _dot_ com>
Date: Tue, 24 Jul 2012 11:12:50 +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 93a2153..3887159 100644
--- a/src/clientlist.c
+++ b/src/clientlist.c
@@ -368,7 +368,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?
@@ -431,7 +431,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);
     }
 }
 
@@ -621,7 +621,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 5b2b151fe555ae8ca5b51d32eac9e4cd6b9b0f83 Mon Sep 17 00:00:00 2001
From: Bastien Dejean <nihilhill _at_ gmail _dot_ com>
Date: Tue, 24 Jul 2012 13:11:30 +0200
Subject: [PATCH 2/2] New setting: window_border_inner_width, removed obsolete double_window_border

---
 NEWS                 |  3 +--
 doc/herbstluftwm.txt |  9 +++------
 src/clientlist.c     | 16 ++++++++--------
 src/settings.c       |  2 +-
 4 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/NEWS b/NEWS
index dac2d5d..06f26c2 100644
--- a/NEWS
+++ b/NEWS
@@ -27,8 +27,7 @@ Changes:
     * only one Makefile for herbstluftwm and herbstclient. The herbstclient
       binary now is put in the main directory.
     * new settings: smart_frame_surroundings and smart_window_surroundings
-    * new setting: double_window_border
-    * new setting: window_border_inner_color
+    * new settings: window_border_inner_color and window_border_inner_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..c82279d 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_border_inner_width (Integer)::
+    Width of the inner border of a window.
+
 window_border_active_color (String/Color)::
     Border color of a focused window.
 
@@ -630,12 +633,6 @@ smart_window_surroundings (Integer)::
     If set, window borders and gaps will be removed when there's no ambiguity
     regarding the focused window.
 
-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.
-
 focus_follows_shift (Integer)::
     If set, focus stays in the window, if window is shifted to another frame.
     If unset, focus stays in the frame.
diff --git a/src/clientlist.c b/src/clientlist.c
index 3887159..74e988f 100644
--- a/src/clientlist.c
+++ b/src/clientlist.c
@@ -31,10 +31,10 @@
 int g_monitor_float_treshold = 24;
 
 int* g_window_border_width;
+int* g_window_border_inner_width;
 int* g_raise_on_focus;
 int* g_snap_gap;
 int* g_smart_window_surroundings;
-int* g_double_window_border;
 unsigned long g_window_border_active_color;
 unsigned long g_window_border_normal_color;
 unsigned long g_window_border_urgent_color;
@@ -60,10 +60,10 @@ static HSClient* create_client() {
 
 static void fetch_colors() {
     g_window_border_width = &(settings_find("window_border_width")->value.i);
+    g_window_border_inner_width = &(settings_find("window_border_inner_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);
-    g_double_window_border = &(settings_find("double_window_border")->value.i);
     g_raise_on_focus = &(settings_find("raise_on_focus")->value.i);
     char* str = settings_find("window_border_normal_color")->value.s;
     g_window_border_normal_color = getcolor(str);
@@ -365,10 +365,10 @@ 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_window_border_inner_width > 0 && *g_window_border_inner_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_border_inner_width, g_window_border_inner_color, current_border_color);
     }
     //// send new size to client
     //// WHY SHOULD I? -> faster? only one call?
@@ -428,10 +428,10 @@ 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_window_border_inner_width > 0 && *g_window_border_inner_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_border_inner_width, g_window_border_inner_color, current_border_color);
     }
 }
 
@@ -620,8 +620,8 @@ 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_window_border_inner_width > 0 && *g_window_border_inner_width < *g_window_border_width) {
+        set_window_double_border(g_display, window, *g_window_border_inner_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..5d50b29 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_border_inner_width",       0,           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   ),
@@ -65,7 +66,6 @@ SettingsPair g_settings[] = {
     SET_INT(    "gapless_grid",                    1,           RELAYOUT    ),
     SET_INT(    "smart_frame_surroundings",        0,           RELAYOUT    ),
     SET_INT(    "smart_window_surroundings",       0,           RELAYOUT    ),
-    SET_INT(    "double_window_border",            0,           RELAYOUT    ),
     SET_INT(    "monitors_locked",                 0,           LOCK_CHANGED),
     SET_INT(    "auto_detect_monitors",            0,           NULL        ),
     SET_STRING( "tree_style",                      "*| +`--.",  FR_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/