1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-23 18:47:57 +00:00

Improve window dividers code.

* faces.el (window-divider): New default value.  Rewrite
doc-string.
(window-divider-first-pixel, window-divider-last-pixel): New
faces.
* dispextern.h (face_id): Add WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID
and WINDOW_DIVIDER_LAST_PIXEL_FACE_ID.
* w32term.c (w32_draw_window_divider): Handle first and last
pixels specially.
* w32term.h (w32_fill_area_abs): New function.
* xdisp.c (x_draw_right_divider): Don't draw over bottom
divider.
* xfaces.c (realize_basic_faces): Handle new face ids.
* xfns.c (Fx_create_frame): Call x_default_parameter for right
and bottom divider width.
* xterm.c (x_draw_window_divider): Handle first and last pixels
specially.
This commit is contained in:
Martin Rudalics 2014-02-04 08:36:58 +01:00
parent 6da8227cfa
commit 764ec9e5f0
11 changed files with 163 additions and 23 deletions

View File

@ -196,6 +196,18 @@ command `frame-configuration-to-register' still exists, but is unbound.
*** New hooks `focus-in-hook', `focus-out-hook'.
These are normal hooks run when an Emacs frame gains or loses input focus.
---
*** Emacs can now draw dividers between adjacent windows. To put
dividers between side-by-side windows customize the frame parameter
right-divider-width to some positive integer. To put dividers between
vertically stacked windows set the frame parameter bottom-divider-width
to some positive integer. Dividers can be dragged with the mouse and
show a corresponding cursor when the mouse hovers over them. The
appearance of dividers can be changed by customizing the basic faces
window-divider, window-divider-first-pixel and window-divider-last-pixel
where the latter two are useful to provide a 3D effect or to better set
dividers apart from surrounding display objects.
---
*** `split-window' is now a non-interactive function, not a command.
As a command, it was a special case of `C-x 2' (`split-window-below'),

View File

@ -1,3 +1,10 @@
2014-02-03 Martin Rudalics <rudalics@gmx.at>
* faces.el (window-divider): New default value. Rewrite
doc-string.
(window-divider-first-pixel, window-divider-last-pixel): New
faces.
2014-02-03 Dmitry Gutov <dgutov@yandex.ru>
* progmodes/ruby-mode.el (ruby-font-lock-keywords): `private',

View File

@ -2425,6 +2425,39 @@ Use the face `mode-line-highlight' for features that can be selected."
:version "22.1"
:group 'basic-faces)
(defface window-divider '((t :foreground "gray60"))
"Basic face for window dividers.
When a divider is less than 3 pixels wide, it is drawn solidly
with the foreground of this face. For larger dividers this face
is used for the inner part while the first pixel line/column is
drawn with the `window-divider-first-pixel' face and the last
pixel line/column with the `window-divider-last-pixel' face."
:version "24.4"
:group 'frames
:group 'basic-faces)
(defface window-divider-first-pixel
'((t :foreground "gray80"))
"Basic face for first pixel line/column of window dividers.
When a divider is at least 3 pixels wide, its first pixel
line/column is drawn with the foreground of this face. If you do
not want to accentuate the first pixel line/column, set this to
the same as `window-divider' face."
:version "24.4"
:group 'frames
:group 'basic-faces)
(defface window-divider-last-pixel
'((t :foreground "gray40"))
"Basic face for last pixel line/column of window dividers.
When a divider is at least 3 pixels wide, its last pixel
line/column is drawn with the foreground of this face. If you do
not want to accentuate the last pixel line/column, set this to
the same as `window-divider' face."
:version "24.4"
:group 'frames
:group 'basic-faces)
(defface minibuffer-prompt
'((((background dark)) :foreground "cyan")
;; Don't use blue because many users of the MS-DOS port customize

View File

@ -1,3 +1,18 @@
2014-02-03 Martin Rudalics <rudalics@gmx.at>
* dispextern.h (face_id): Add WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID
and WINDOW_DIVIDER_LAST_PIXEL_FACE_ID.
* w32term.c (w32_draw_window_divider): Handle first and last
pixels specially.
* w32term.h (w32_fill_area_abs): New function.
* xdisp.c (x_draw_right_divider): Don't draw over bottom
divider.
* xfaces.c (realize_basic_faces): Handle new face ids.
* xfns.c (Fx_create_frame): Call x_default_parameter for right
and bottom divider width.
* xterm.c (x_draw_window_divider): Handle first and last pixels
specially.
2014-02-03 Dmitry Antipov <dmantipov@yandex.ru>
* print.c (Fexternal_debugging_output): Add cast to pacify

View File

@ -1765,6 +1765,8 @@ enum face_id
MENU_FACE_ID,
VERTICAL_BORDER_FACE_ID,
WINDOW_DIVIDER_FACE_ID,
WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID,
WINDOW_DIVIDER_LAST_PIXEL_FACE_ID,
BASIC_FACE_ID_SENTINEL
};

View File

@ -628,26 +628,38 @@ static void
w32_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
RECT r;
HDC hdc;
struct face *face;
HDC hdc = get_frame_dc (f);
struct face *face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
struct face *face_first = FACE_FROM_ID (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
struct face *face_last = FACE_FROM_ID (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
unsigned long color_first = (face_first
? face_first->foreground
: FRAME_FOREGROUND_PIXEL (f));
unsigned long color_last = (face_last
? face_last->foreground
: FRAME_FOREGROUND_PIXEL (f));
r.left = x0;
r.right = x1;
r.top = y0;
r.bottom = y1;
hdc = get_frame_dc (f);
face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
if (face)
w32_fill_rect (f, hdc, face->foreground, &r);
if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
/* Vertical. */
{
w32_fill_area_abs (f, hdc, color_first, x0, y0, x0 + 1, y1);
w32_fill_area_abs (f, hdc, color, x0 + 1, y0, x1 - 1, y1);
w32_fill_area_abs (f, hdc, color_last, x1 - 1, y0, x1, y1);
}
else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
/* Horizontal. */
{
w32_fill_area_abs (f, hdc, color_first, x0, y0, x1, y0 + 1);
w32_fill_area_abs (f, hdc, color, x0, y0 + 1, x1, y1 - 1);
w32_fill_area_abs (f, hdc, color_last, x0, y1 - 1, x1, y1);
}
else
w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
w32_fill_area_abs (f, hdc, color, x0, y0, x1, y1);
release_frame_dc (f, hdc);
}
/* End update of window W.
Draw vertical borders between horizontally adjacent windows, and

View File

@ -537,6 +537,16 @@ do { \
w32_fill_rect (f,hdc,pix,&rect); \
} while (0)
#define w32_fill_area_abs(f,hdc,pix,x0,y0,x1,y1) \
do { \
RECT rect; \
rect.left = x0; \
rect.top = y0; \
rect.right = x1; \
rect.bottom = y1; \
w32_fill_rect (f,hdc,pix,&rect); \
} while (0)
#define w32_clear_rect(f,hdc,lprect) \
w32_fill_rect (f, hdc, FRAME_BACKGROUND_PIXEL (f), lprect)

View File

@ -29277,7 +29277,8 @@ x_draw_right_divider (struct window *w)
int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
int x1 = WINDOW_RIGHT_EDGE_X (w);
int y0 = WINDOW_TOP_EDGE_Y (w);
int y1 = WINDOW_BOTTOM_EDGE_Y (w);
/* The bottom divider prevails. */
int y1 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
}

View File

@ -324,6 +324,8 @@ static Lisp_Object Qborder, Qmouse, Qmenu;
Lisp_Object Qmode_line_inactive;
static Lisp_Object Qvertical_border;
static Lisp_Object Qwindow_divider;
static Lisp_Object Qwindow_divider_first_pixel;
static Lisp_Object Qwindow_divider_last_pixel;
/* The symbol `face-alias'. A symbols having that property is an
alias for another face. Value of the property is the name of
@ -5249,6 +5251,10 @@ realize_basic_faces (struct frame *f)
realize_named_face (f, Qmenu, MENU_FACE_ID);
realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
realize_named_face (f, Qwindow_divider, WINDOW_DIVIDER_FACE_ID);
realize_named_face (f, Qwindow_divider_first_pixel,
WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
realize_named_face (f, Qwindow_divider_last_pixel,
WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
/* Reflect changes in the `menu' face in menu bars. */
if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
@ -6452,6 +6458,8 @@ syms_of_xfaces (void)
DEFSYM (Qmode_line_inactive, "mode-line-inactive");
DEFSYM (Qvertical_border, "vertical-border");
DEFSYM (Qwindow_divider, "window-divider");
DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel");
DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel");
DEFSYM (Qtty_color_desc, "tty-color-desc");
DEFSYM (Qtty_color_standard_values, "tty-color-standard-values");
DEFSYM (Qtty_color_by_index, "tty-color-by-index");

View File

@ -3033,6 +3033,10 @@ This function is an internal primitive--use `make-frame' instead. */)
#endif
"internalBorderWidth", "internalBorderWidth",
RES_TYPE_NUMBER);
x_default_parameter (f, parms, Qright_divider_width, make_number (0),
NULL, NULL, RES_TYPE_NUMBER);
x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
NULL, NULL, RES_TYPE_NUMBER);
x_default_parameter (f, parms, Qvertical_scroll_bars,
#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
Qright,

View File

@ -510,15 +510,51 @@ static void
x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
struct face *face;
struct face *face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
struct face *face_first = FACE_FROM_ID (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
struct face *face_last = FACE_FROM_ID (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
unsigned long color_first = (face_first
? face_first->foreground
: FRAME_FOREGROUND_PIXEL (f));
unsigned long color_last = (face_last
? face_last->foreground
: FRAME_FOREGROUND_PIXEL (f));
Display *display = FRAME_X_DISPLAY (f);
Window window = FRAME_X_WINDOW (f);
face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
if (face)
XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
face->foreground);
XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
f->output_data.x->normal_gc, x0, y0, x1 - x0, y1 - y0);
if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
/* Vertical. */
{
XSetForeground (display, f->output_data.x->normal_gc, color_first);
XFillRectangle (display, window, f->output_data.x->normal_gc,
x0, y0, 1, y1 - y0);
XSetForeground (display, f->output_data.x->normal_gc, color);
XFillRectangle (display, window, f->output_data.x->normal_gc,
x0 + 1, y0, x1 - x0 - 2, y1 - y0);
XSetForeground (display, f->output_data.x->normal_gc, color_last);
XFillRectangle (display, window, f->output_data.x->normal_gc,
x1 - 1, y0, 1, y1 - y0);
}
else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
/* Horizontal. */
{
XSetForeground (display, f->output_data.x->normal_gc, color_first);
XFillRectangle (display, window, f->output_data.x->normal_gc,
x0, y0, x1 - x0, 1);
XSetForeground (display, f->output_data.x->normal_gc, color);
XFillRectangle (display, window, f->output_data.x->normal_gc,
x0, y0 + 1, x1 - x0, y1 - y0 - 2);
XSetForeground (display, f->output_data.x->normal_gc, color_last);
XFillRectangle (display, window, f->output_data.x->normal_gc,
x0, y1 - 1, x1 - x0, 1);
}
else
{
XSetForeground (display, f->output_data.x->normal_gc, color);
XFillRectangle (display, window, f->output_data.x->normal_gc,
x0, y0, x1 - x0, y1 - y0);
}
}
/* End update of window W.