[PATCH] Allow themes to utilize X window borders



Add two new attributes to frame part definition, border-width and
border-color.  Their values are then passed to XSetWindowBorderWidth
and XSetWindowBorder functions.

Signed-off-by: Alexey I. Froloff <raorn altlinux org>
---
 man/sawfish.texi |   18 ++++++++++++++----
 src/events.c     |    2 +-
 src/frames.c     |   41 +++++++++++++++++++++++++++++++++++++----
 src/sawfish.h    |    3 +++
 src/windows.c    |   10 ++++++----
 5 files changed, 61 insertions(+), 13 deletions(-)

diff --git a/man/sawfish.texi b/man/sawfish.texi
index 5be59c8..ca182c4 100644
--- a/man/sawfish.texi
+++ b/man/sawfish.texi
@@ -3540,6 +3540,12 @@ Defines the width of the frame part.
 @item (height . @var{value})
 Defines the height of the frame part.
 
+ item (border-width . @var{value})
+Defines window border width.
+
+ item (border-color . @var{value})
+Defines window border color.
+
 @item (keymap . @var{value})
 Defines the keymap to use when evaluating events originating in this
 frame part.
@@ -3569,10 +3575,14 @@ frame part.
 The values specified for the @code{background}, @code{foreground},
 @code{render-scale}, @code{font}, @code{left-edge}, @code{right-edge},
 @code{top-edge}, @code{bottom-edge}, @code{width}, @code{height},
- code{cursor}, @code{below-client} and @code{hidden} attributes may
-actually be functions. In which case the function will be called (with
-a single argument, the window object) when the frame is constructed,
-the value returned will be used as the actual value of the attribute.
+ code{border-color}, @code{cursor}, @code{below-client} and
+ code{hidden} attributes may actually be functions. In which case the
+function will be called (with a single argument, the window object)
+when the frame is constructed, the value returned will be used as the
+actual value of the attribute.
+
+The values specified for the @code{border-width} and @code{border-color}
+are applied for the whole window instead of current frame part.
 
 The coordinate system used for specifying the part's position is
 relative to the window edge that the position is defined against.
diff --git a/src/events.c b/src/events.c
index 6daefd7..1d037fc 100644
--- a/src/events.c
+++ b/src/events.c
@@ -1290,7 +1290,7 @@ send_synthetic_configure (Lisp_Window *w)
 	}
 	ev.xconfigure.width = w->attr.width;
 	ev.xconfigure.height = w->attr.height;
-	ev.xconfigure.border_width = w->attr.border_width;
+	ev.xconfigure.border_width = w->border_width;
 	ev.xconfigure.above = w->reparented ? w->frame : root_window;
 	ev.xconfigure.override_redirect = False;
 	XSendEvent (dpy, w->id, False, StructureNotifyMask, &ev);
diff --git a/src/frames.c b/src/frames.c
index 14e4d10..e359a18 100644
--- a/src/frames.c
+++ b/src/frames.c
@@ -86,6 +86,8 @@ DEFSYM(override_frame_part_classes, "override-frame-part-classes");
 DEFSYM(below_client, "below-client");
 DEFSYM(scale_foreground, "scale-foreground");
 DEFSYM(hidden, "hidden");
+DEFSYM(border_width, "border-width");
+DEFSYM(border_color, "border-color");
 
 static repv state_syms[fps_MAX];
 
@@ -215,6 +217,9 @@ fp_sweep (void)
 	height . PIXELS
 	width . PIXELS
 
+	border-width . NUMBER
+	border-color . COLOR
+
 	keymap . KEYMAP
 	cursor . CURSOR-OR-CURSOR-DEF
 
@@ -338,11 +343,11 @@ set_frame_shapes (Lisp_Window *w, bool atomic)
 	XSetWindowAttributes wa;
 	int wamask;
 	wa.colormap = image_cmap;
-	wa.border_pixel = BlackPixel (dpy, screen_num);
+	wa.border_pixel = w->border_pixel;
 	wamask = CWColormap | CWBorderPixel;
 	shape_win = XCreateWindow (dpy, root_window, -100, -100,
 				   w->frame_width, w->frame_height,
-				   0, image_depth, InputOutput,
+				   w->border_width, image_depth, InputOutput,
 				   image_visual, wamask, &wa);
     }
     else
@@ -1246,6 +1251,26 @@ build_frame_part (struct frame_part *fp)
     else
 	fp->renderer = Qnil;
 
+    /* get border width */
+    tem = get_integer_prop (fp, Qborder_width, class_elt, ov_class_elt);
+    if (tem != Qnil) {
+	w->border_width = rep_INT(tem);
+    }
+
+    /* get border color */
+    tem = fp_assq (fp, Qborder_color, class_elt, ov_class_elt);
+    if (tem != Qnil)
+    {
+	tem = rep_CDR(tem);
+	if (Ffunctionp (tem) != Qnil)
+	    tem = call_protectedly_1 (tem, rep_VAL (w), Qnil);
+	if (!COLORP(tem) && tem != Qnil)
+	    tem = call_protectedly (get_color, tem, Qnil);
+	if (COLORP(tem)) {
+	    w->border_pixel = VCOLOR(tem)->pixel;
+	}
+    }
+
     /* get background images or colors */
     if (!get_pattern_prop (fp, fp->bg, get_color,
 			   Qbackground, class_elt, ov_class_elt))
@@ -1487,6 +1512,10 @@ list_frame_generator (Lisp_Window *w)
 
     rep_PUSHGC(gc_win, win);
 
+    /* clear window border */
+    w->border_width = 0;
+    w->border_pixel = BlackPixel (dpy, screen_num);
+
     /* construct the component list, and find the bounding box */
 
     /* if w->destroy_frame is set then we're rebuilding an existing
@@ -1581,12 +1610,12 @@ list_frame_generator (Lisp_Window *w)
 
 	wa.override_redirect = True;
 	wa.colormap = colormap;
-	wa.border_pixel = BlackPixel (dpy, screen_num);
+	wa.border_pixel = w->border_pixel;
 	wa.save_under = w->attr.save_under;
 	wamask = CWOverrideRedirect | CWColormap | CWBorderPixel | CWSaveUnder;
 
 	w->frame = XCreateWindow (dpy, root_window, w->attr.x, w->attr.y,
-				  w->frame_width, w->frame_height, 0,
+				  w->frame_width, w->frame_height, w->border_width,
 				  depth, InputOutput, visual, wamask, &wa);
     }
     else
@@ -1595,6 +1624,8 @@ list_frame_generator (Lisp_Window *w)
 	w->attr.x += w->frame_x - old_x_off;
 	w->attr.y += w->frame_y - old_y_off;
 
+	XSetWindowBorder (dpy, w->frame, w->border_pixel);
+	XSetWindowBorderWidth (dpy, w->frame, w->border_width);
 	XMoveResizeWindow (dpy, w->frame, w->attr.x, w->attr.y,
 			   w->frame_width, w->frame_height);
 
@@ -1966,6 +1997,8 @@ frames_init (void)
     rep_INTERN(below_client);
     rep_INTERN(scale_foreground);
     rep_INTERN(hidden);
+    rep_INTERN(border_width);
+    rep_INTERN(border_color);
 
     rep_INTERN_SPECIAL(frame_part_classes);
     rep_INTERN_SPECIAL(override_frame_part_classes);
diff --git a/src/sawfish.h b/src/sawfish.h
index 1a6fb7e..69162b8 100644
--- a/src/sawfish.h
+++ b/src/sawfish.h
@@ -142,6 +142,9 @@ typedef struct lisp_window {
        But the position is the position of the frame, while the
        dimensions are those of the client */
     XWindowAttributes attr;
+    unsigned int old_border_width;		/* saved border width of window */
+    unsigned int border_width;
+    unsigned long border_pixel;
     XSizeHints hints;
     XWMHints *wmhints;
     Window *cmap_windows;
diff --git a/src/windows.c b/src/windows.c
index 330f763..3d2dd42 100644
--- a/src/windows.c
+++ b/src/windows.c
@@ -458,6 +458,7 @@ add_window (Window id)
 	w->name = rep_null_string ();
 	w->net_name = Qnil;
 	w->net_icon_name = Qnil;
+	w->border_pixel = BlackPixel (dpy, screen_num);
 
         /* Don't garbage collect the window before we are done. */
         /* Note: must not return without rep_POPGC. */
@@ -473,6 +474,7 @@ add_window (Window id)
 	XGetWindowAttributes (dpy, id, &w->attr);
 	DB(("  orig: width=%d height=%d x=%d y=%d\n",
 	    w->attr.width, w->attr.height, w->attr.x, w->attr.y));
+	w->old_border_width = w->attr.border_width;
 
 	get_window_name(w);
 
@@ -599,7 +601,7 @@ remove_window (Lisp_Window *w, bool destroyed, bool from_error)
 	    remove_window_frame (w);
 
 	    /* Restore original border width of the client */
-	    XSetWindowBorderWidth (dpy, w->id, w->attr.border_width);
+	    XSetWindowBorderWidth (dpy, w->id, w->old_border_width);
 	}
 
 	if (!from_error)
@@ -960,8 +962,8 @@ surrounding WINDOW.
     rep_DECLARE1(win, WINDOWP);
     if (VWIN(win)->reparented)
     {
-	return Fcons (rep_MAKE_INT(VWIN(win)->frame_width),
-		      rep_MAKE_INT(VWIN(win)->frame_height));
+	return Fcons (rep_MAKE_INT(VWIN(win)->frame_width + 2*VWIN(win)->border_width),
+		      rep_MAKE_INT(VWIN(win)->frame_height + 2*VWIN(win)->border_width));
     }
     else
 	return Fwindow_dimensions (win);
@@ -1262,7 +1264,7 @@ window-border-width WINDOW
 ::end:: */
 {
     rep_DECLARE1(win, WINDOWP);
-    return rep_MAKE_INT(VWIN(win)->attr.border_width);
+    return rep_MAKE_INT(VWIN(win)->border_width);
 }
 
 DEFUN("window-size-hints", Fwindow_size_hints, Swindow_size_hints,
-- 
1.7.0.4



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