I tried to fix a bug reported by Hrvoje, when no divider appears between
two windows of which left has left scrollbar, and the right has right
scrollbar. While combing thru the code it become clear how easy it is
to implement draggable window dividers (it appeared the false impression
when it came down to writing lisp function which handles the drag. Better
do not read it :)
Visually, draggable dividers suck under X. With out of the box default
coloring, they are invisible at all. In the patch, I changed the divider
color under X to that of modeline foreground (it was background), so they
became black. Oh too black...
I was going to implement a separate face for dividers, but there's a much
better soultion: make the dividers 3-D, just like the modeline, what
Jonathan actually did under Windows from the very beginning. I looked
at the code which draws 3-D border around modeline, and understood that
this is beyond my powers to do this myself. Any good soul out there can
make this under X? Picture attached ;)
Kirill
ChangeLog entry for src/
1998-05-12 Kirill M. Katsnelson <kkm(a)kis.ru>
* window.c (window_needs_vertical_divider): Enable vertical
dividers for every non-rightmost window.
(window_left_gutter_width): Left gutter consists of mythical
toolbar and a virtual scrollbar.
(window_right_gutter_width): The right one may have a divider
also.
* scrollbar.c (update_scrollbar_instance): Position vertical
scrollbar left to divider if the latter present.
* redisplay.h: Declared OVER_DIVIER constant.
* redisplay.c (pixel_to_glyph_translation): Handle OVER_DIVIDER
case.
* redisplay-x.c (x_output_vertical_divider): Output divider along
the right side of the window, down to window bottom. Swapped
foreground and background colors so it is visible by default.
* redisplay-tty.c (tty_output_vertical_divider): Uncondiionally
stick the divider to the right window side.
* redisplay-msw.c (mswindows_redisplay_deadbox_maybe): Fixed
deadbox painting.
(mswindows_divider_width): Ask system for user preferred value.
(mswindows_output_vertical_divider): Always output the divider on
the right side of a window, down to bottom.
* keymap.c (get_relevant_keymaps): Route mouse button events which
happened over a window divider through window-divider-map.
(Fkey_binding): Documented that in the docstring.
Defined the variable Vwindow_divider_map.
* events.c (Fevent_over_divider_p): Added this function.
* events.h: EXFUNed it.
ChangeLog entry for lisp/
1998-05-12 Kirill M. Katsnelson <kkm(a)kis.ru>
* glyphs.el (divider-pointer-glyph): Declared new glyph,
E-W arrow pointer displayed over draggable dividers.
* mouse.el (default-mouse-motion-handler): Show it when
appropriate.
(drag-window-divider): Added.
([top-level]): Initialized window-divider-map with a keymap
binding the above function to left button down event.
* x-mouse.el (x-init-pointer-shape): Initialize
divider-pointer-glyph from Cursor.dividerPointer, or use default
E-W double arrow.
Index: src/events.c
===================================================================
RCS file: /var/cvsroot/ntxemacs/src/events.c,v
retrieving revision 1.1.1.12
diff -u -r1.1.1.12 events.c
--- src/events.c 1998/05/10 13:00:41 1.1.1.12
+++ src/events.c 1998/05/11 00:25:23
@@ -1648,6 +1648,7 @@
OVER_NOTHING: over the text area, but not over text
OVER_OUTSIDE: outside of the frame border
OVER_TEXT: over text in the text area
+ OVER_DIVIDER: over windows divider
and return:
@@ -1792,6 +1793,16 @@
return result == OVER_TOOLBAR ? Qt : Qnil;
}
+DEFUN ("event-over-divider-p", Fevent_over_divider_p, 1, 1, 0, /*
+Return t if the mouse event EVENT occurred over a window divider.
+*/
+ (event))
+{
+ int result = event_pixel_translation (event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+ return result == OVER_DIVIDER ? Qt : Qnil;
+}
+
struct console *
event_console_or_selected (Lisp_Object event)
{
@@ -2160,6 +2171,7 @@
DEFSUBR (Fevent_over_modeline_p);
DEFSUBR (Fevent_over_border_p);
DEFSUBR (Fevent_over_toolbar_p);
+ DEFSUBR (Fevent_over_divider_p);
DEFSUBR (Fevent_channel);
DEFSUBR (Fevent_window);
DEFSUBR (Fevent_point);
Index: src/events.h
===================================================================
RCS file: /var/cvsroot/ntxemacs/src/events.h,v
retrieving revision 1.7
diff -u -r1.7 events.h
--- src/events.h 1998/05/10 16:12:55 1.7
+++ src/events.h 1998/05/11 00:20:53
@@ -504,6 +504,7 @@
EXFUN (Fevent_modeline_position, 1);
EXFUN (Fevent_over_modeline_p, 1);
EXFUN (Fevent_over_toolbar_p, 1);
+EXFUN (Fevent_over_divider_p, 1);
EXFUN (Fevent_point, 1);
EXFUN (Fevent_window, 1);
EXFUN (Fmake_event, 2);
Index: src/keymap.c
===================================================================
RCS file: /var/cvsroot/ntxemacs/src/keymap.c,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 keymap.c
--- src/keymap.c 1998/05/10 13:01:15 1.1.1.8
+++ src/keymap.c 1998/05/11 00:22:37
@@ -208,6 +208,8 @@
static Lisp_Object Vkey_translation_map;
+static Lisp_Object Vwindow_divider_map;
+
/* This is incremented whenever a change is made to a keymap. This is
so that things which care (such as the menubar code) can recompute
privately-cached data when the user has changed keybindings.
@@ -2332,6 +2334,7 @@
else
{
/* It's a mouse event; order of keymaps searched is:
+ o window-divider-map, if event is over a divider
o local-map of mouse-grabbed-buffer
o keymap of any/all extents under the mouse
if the mouse is over a modeline:
@@ -2343,6 +2346,12 @@
*/
Lisp_Object window = Fevent_window (terminal);
+ if (!NILP (Fevent_over_divider_p (terminal)))
+ {
+ if (KEYMAPP (Vwindow_divider_map))
+ relevant_map_push (Vwindow_divider_map, &closure);
+ }
+
if (BUFFERP (Vmouse_grabbed_buffer))
{
Lisp_Object map = XBUFFER (Vmouse_grabbed_buffer)->keymap;
@@ -2535,6 +2544,7 @@
For mouse-clicks, the order of keymaps searched is:
- the current-local-map of the `mouse-grabbed-buffer' if any;
+ - window-divider-map, if the event happened over a window divider
- the `keymap' property of any extent(s) at the position of the click
(this includes modeline extents);
- the modeline-map of the buffer corresponding to the modeline under
@@ -4314,6 +4324,10 @@
Keymap of key translations that can override keymaps.
This keymap works like `function-key-map', but comes after that,
and applies even for keys that have ordinary bindings.
+*/ );
+
+ DEFVAR_LISP ("window-divider-map", &Vwindow_divider_map /*
+Keymap which handles mouse clicks over window dividers.
*/ );
DEFVAR_INT ("keymap-tick", &keymap_tick /*
Index: src/redisplay-msw.c
===================================================================
RCS file: /var/cvsroot/ntxemacs/src/redisplay-msw.c,v
retrieving revision 1.11
diff -u -r1.11 redisplay-msw.c
--- src/redisplay-msw.c 1998/05/10 16:13:12 1.11
+++ src/redisplay-msw.c 1998/05/11 15:16:09
@@ -51,14 +51,6 @@
#include "mule-charset.h"
#endif
-/* MSWINDOWS_DIVIDER_LINE_WIDTH is the width of the line drawn in the gutter.
- MSWINDOWS_DIVIDER_SPACING is the amount of blank space on each side of the line.
- MSWINDOWS_DIVIDER_WIDTH = MSWINDOWS_DIVIDER_LINE_WIDTH + 2*MSWINDOWS_DIVIDER_SPACING
-*/
-#define MSWINDOWS_DIVIDER_LINE_WIDTH 7
-#define MSWINDOWS_DIVIDER_SPACING 0
-#define MSWINDOWS_DIVIDER_WIDTH (MSWINDOWS_DIVIDER_LINE_WIDTH + 2 *
MSWINDOWS_DIVIDER_SPACING)
-
#define MSWINDOWS_EOL_CURSOR_WIDTH 5
/*
@@ -77,6 +69,8 @@
face_index findex, int cursor_start,
int cursor_width, int cursor_height);
+static int divider_width = 0;
+
typedef struct textual_run
{
Lisp_Object charset;
@@ -696,27 +690,16 @@
return;
if (!NILP (w->scrollbar_on_left_p))
- {
- rect_dead.left = WINDOW_LEFT (w);
- rect_dead.right = WINDOW_LEFT (w) + sbw;
- }
+ rect_dead.left = WINDOW_LEFT (w);
else
- {
- rect_dead.left = WINDOW_RIGHT (w) - sbw;
- rect_dead.right = WINDOW_RIGHT (w);
- }
+ rect_dead.left = WINDOW_TEXT_RIGHT (w);
+ rect_dead.right = rect_dead.left + sbw;
if (!NILP (w->scrollbar_on_top_p))
- {
- rect_dead.top = WINDOW_TOP (w);
- rect_dead.bottom = WINDOW_TOP (w) + sbh;
- }
+ rect_dead.top = WINDOW_TOP (w);
else
- {
- int modh = window_modeline_height (w);
- rect_dead.top = WINDOW_BOTTOM (w) - modh - sbh;
- rect_dead.bottom = WINDOW_BOTTOM (w) - modh;
- }
+ rect_dead.top = WINDOW_TEXT_BOTTOM (w);
+ rect_dead.bottom = rect_dead.top + sbh;
if (IntersectRect (&rect_paint, &rect_dead, prc))
{
@@ -903,7 +886,11 @@
static int
mswindows_divider_width (void)
{
- return MSWINDOWS_DIVIDER_WIDTH;
+ if (divider_width == 0)
+ divider_width = (GetSystemMetrics (SM_CXSIZEFRAME)
+ + GetSystemMetrics (SM_CXEDGE));
+
+ return divider_width;
}
/*****************************************************************************
@@ -1187,50 +1174,20 @@
/*****************************************************************************
mswindows_output_vertical_divider
- Draw a vertical divider down the left side of the given window.
+ Draw a vertical divider down the right side of the given window.
****************************************************************************/
static void
-mswindows_output_vertical_divider (struct window *w, int clear)
+mswindows_output_vertical_divider (struct window *w, int clear_unused)
{
struct frame *f = XFRAME (w->frame);
- Lisp_Object color;
RECT rect;
- int shadow_width = MODELINE_SHADOW_THICKNESS (w);
- /* We don't use the normal gutter measurements here because the
- horizontal scrollbars and toolbars do not stretch completely over
- to the right edge of the window. Only the modeline does. */
- int modeline_height = window_modeline_height (w);
+ rect.right = WINDOW_RIGHT (w);
+ rect.left = rect.right - mswindows_divider_width ();
+ rect.top = WINDOW_TOP (w);
+ rect.bottom = WINDOW_BOTTOM (w);
- assert(!MSWINDOWS_DIVIDER_SPACING); /* This code doesn't handle this */
-
- /* XXX Not sure about this */
-#ifdef HAVE_SCROLLBARS
- if (!NILP (w->scrollbar_on_left_p))
- rect.left = WINDOW_LEFT (w);
- else
- rect.left = WINDOW_RIGHT (w) - MSWINDOWS_DIVIDER_WIDTH;
-#else
- rect.left = WINDOW_LEFT (w);
-#endif
- rect.right = rect.left + MSWINDOWS_DIVIDER_WIDTH;
-
-#ifdef HAVE_SCROLLBARS
- if (!NILP (w->scrollbar_on_top_p))
- rect.top = WINDOW_TOP (w);
- else
-#endif
- rect.top = WINDOW_TEXT_TOP (w);
- rect.bottom = WINDOW_BOTTOM (w) - modeline_height;
-
- /* Draw the divider line */
- color = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX);
- mswindows_update_dc (FRAME_MSWINDOWS_DC(f), Qnil, Qnil, color, Qnil);
- ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
- if (shadow_width)
- DrawEdge (FRAME_MSWINDOWS_DC (f), &rect,
- shadow_width==1 ? BDR_RAISEDINNER : EDGE_RAISED,
- BF_TOP|BF_RIGHT|BF_LEFT);
+ DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
}
Index: src/redisplay-tty.c
===================================================================
RCS file: /var/cvsroot/ntxemacs/src/redisplay-tty.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 redisplay-tty.c
--- src/redisplay-tty.c 1998/04/05 13:07:24 1.1.1.4
+++ src/redisplay-tty.c 1998/05/11 15:27:06
@@ -436,7 +436,7 @@
/*****************************************************************************
tty_output_vertical_divider
- Draw a vertical divider down the left side of the given window.
+ Draw a vertical divider down the right side of the given window.
****************************************************************************/
static void
tty_output_vertical_divider (struct window *w, int clear)
@@ -451,13 +451,13 @@
tty_turn_on_face (w, MODELINE_INDEX);
for (line = y_top; line < y_bot; line++)
{
- cmgoto (f, line, WINDOW_TEXT_LEFT (w) - 1);
+ cmgoto (f, line, WINDOW_TEXT_RIGHT (w));
send_string_to_tty_console (c, &divv, 1);
TTY_INC_CURSOR_X (c, 1);
}
/* Draw the divider in the modeline. */
- cmgoto (f, y_bot, WINDOW_TEXT_LEFT (w) - 1);
+ cmgoto (f, y_bot, WINDOW_TEXT_RIGHT (w));
send_string_to_tty_console (c, &divv, 1);
TTY_INC_CURSOR_X (c, 1);
tty_turn_off_face (w, MODELINE_INDEX);
Index: src/redisplay-x.c
===================================================================
RCS file: /var/cvsroot/ntxemacs/src/redisplay-x.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 redisplay-x.c
--- src/redisplay-x.c 1998/05/10 13:02:03 1.1.1.7
+++ src/redisplay-x.c 1998/05/11 17:53:10
@@ -1388,7 +1388,7 @@
/*****************************************************************************
x_output_vertical_divider
- Draw a vertical divider down the left side of the given window.
+ Draw a vertical divider down the right side of the given window.
****************************************************************************/
static void
x_output_vertical_divider (struct window *w, int clear)
@@ -1400,71 +1400,28 @@
Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
GC gc;
- /* We don't use the normal gutter measurements here because the
- horizontal scrollbars and toolbars do not stretch completely over
- to the right edge of the window. Only the modeline does. */
- int modeline_height = window_modeline_height (w);
- int x1, x2;
- int y1, y2;
-
-#ifdef HAVE_SCROLLBARS
- if (!NILP (w->scrollbar_on_left_p))
-#endif
- x1 = WINDOW_LEFT (w);
-#ifdef HAVE_SCROLLBARS
- else
- x1 = WINDOW_RIGHT (w) - X_DIVIDER_WIDTH;
-#endif
- x2 = x1 + X_DIVIDER_SPACING;
-
-#ifdef HAVE_SCROLLBARS
- if (!NILP (w->scrollbar_on_top_p))
- y1 = WINDOW_TOP (w);
- else
-#endif
- y1 = WINDOW_TEXT_TOP (w);
- y2 = WINDOW_BOTTOM (w) - modeline_height;
-
- /* Draw the divider in the window. */
- {
- /* Clear the divider area first. This needs to be done when a
- window split occurs. */
- if (clear)
- XClearArea (dpy, x_win, x1, y1, X_DIVIDER_WIDTH, y2 - y1, False);
-
- /* #### There needs to be some checks to make sure that whatever
- colors we choose, the line will be visible (not same color as
- default background.
-
- #### No there don't. If I want the vertical divider to be
- invisible, I should be able to make it so. */
- gc = x_get_gc (d, Qnil, WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX),
- WINDOW_FACE_CACHEL_FOREGROUND (w, MODELINE_INDEX),
- Qnil, Qnil);
-
- /* Draw the divider line. */
- XFillRectangle (dpy, x_win, gc, x2, y1, X_DIVIDER_LINE_WIDTH, y2 - y1);
- }
-
- /* Draw the divider in the modeline but only if we are using 2D
- modelines. */
- if (EQ (Qzero, w->modeline_shadow_thickness))
- {
- XFillRectangle (dpy, x_win, gc, x1, y2, X_DIVIDER_WIDTH,
- modeline_height);
-
- /* #### There needs to be some checks to make sure that whatever
- colors we choose, the line will be visible (not same color as
- default background. */
- gc = x_get_gc (d, Qnil,
- WINDOW_FACE_CACHEL_FOREGROUND (w, MODELINE_INDEX),
- WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX),
- Qnil, Qnil);
-
- /* Draw the divider line. */
- XFillRectangle (dpy, x_win, gc, x2, y2, X_DIVIDER_LINE_WIDTH,
- modeline_height);
- }
+ int x = WINDOW_RIGHT (w) - X_DIVIDER_WIDTH;
+ int y1 = WINDOW_TOP (w);
+ int y2 = WINDOW_BOTTOM (w);
+
+ /* Clear the divider area first. This needs to be done when a
+ window split occurs. */
+ if (clear)
+ XClearArea (dpy, x_win, x1, y1, X_DIVIDER_WIDTH, y2 - y1, False);
+
+ /* #### There needs to be some checks to make sure that whatever
+ colors we choose, the line will be visible (not same color as
+ default background.
+
+ #### No there don't. If I want the vertical divider to be
+ invisible, I should be able to make it so. */
+ gc = x_get_gc (d, Qnil, WINDOW_FACE_CACHEL_FOREGROUND (w, MODELINE_INDEX),
+ WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX),
+ Qnil, Qnil);
+
+ /* Draw the divider line. */
+ XFillRectangle (dpy, x_win, gc, x + X_DIVIDER_SPACING, y1,
+ X_DIVIDER_LINE_WIDTH, y2 - y1);
}
/*****************************************************************************
Index: src/redisplay.c
===================================================================
RCS file: /var/cvsroot/ntxemacs/src/redisplay.c,v
retrieving revision 1.11
diff -u -r1.11 redisplay.c
--- src/redisplay.c 1998/05/10 16:13:15 1.11
+++ src/redisplay.c 1998/05/11 00:24:05
@@ -8129,6 +8129,30 @@
UPDATE_CACHE_RETURN;
}
+ /* See if the point is over window divider */
+ if (window_needs_vertical_divider (*w))
+ {
+ int div_x_high = WINDOW_RIGHT (*w);
+ int div_x_low = div_x_high - FRAMEMETH (f, divider_width, ());
+ int div_y_high = WINDOW_BOTTOM (*w);
+#ifdef HAVE_SCROLLBARS
+ int div_y_low = (!NILP ((*w)->scrollbar_on_top_p)
+ ? WINDOW_TOP (*w) : WINDOW_TEXT_TOP (*w));
+#else
+ int div_y_low = WINDOW_TEXT_TOP (*w);
+#endif
+ if (div_x_low < x_coord && x_coord <= div_x_high &&
+ div_y_low < y_coord && y_coord <= div_y_high)
+ {
+ low_x_coord = div_x_low;
+ high_x_coord = div_x_high;
+ low_y_coord = div_y_low;
+ high_y_coord = div_y_high;
+ position = OVER_DIVIDER;
+ UPDATE_CACHE_RETURN;
+ }
+ }
+
dla = window_display_lines (*w, CURRENT_DISP);
for (*row = 0; *row < Dynarr_length (dla); (*row)++)
Index: src/redisplay.h
===================================================================
RCS file: /var/cvsroot/ntxemacs/src/redisplay.h,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 redisplay.h
--- src/redisplay.h 1998/04/05 13:07:30 1.1.1.3
+++ src/redisplay.h 1998/05/10 23:51:18
@@ -37,6 +37,7 @@
#define OVER_NOTHING 3
#define OVER_BORDER 4
#define OVER_TOOLBAR 5
+#define OVER_DIVIDER 6
#define NO_BLOCK -1
Index: src/scrollbar.c
===================================================================
RCS file: /var/cvsroot/ntxemacs/src/scrollbar.c,v
retrieving revision 1.3
diff -u -r1.3 scrollbar.c
--- src/scrollbar.c 1998/05/10 16:13:20 1.3
+++ src/scrollbar.c 1998/05/10 23:22:05
@@ -468,7 +468,9 @@
{
x_offset = (!NILP (w->scrollbar_on_left_p)
? WINDOW_LEFT (w)
- : WINDOW_RIGHT (w) - scrollbar_width);
+ : (WINDOW_RIGHT (w) - scrollbar_width
+ - (window_needs_vertical_divider (w)
+ ? FRAMEMETH (f, divider_width, ()) : 0)));
y_offset = WINDOW_TEXT_TOP (w) + f->scrollbar_y_offset;
}
else
Index: src/window.c
===================================================================
RCS file: /var/cvsroot/ntxemacs/src/window.c,v
retrieving revision 1.1.1.13
diff -u -r1.1.1.13 window.c
--- src/window.c 1998/05/10 13:02:44 1.1.1.13
+++ src/window.c 1998/05/10 23:15:06
@@ -778,14 +778,7 @@
int
window_needs_vertical_divider (struct window *w)
{
-#ifdef HAVE_SCROLLBARS
- return (!window_scrollbar_width (w) &&
- (!NILP (w->scrollbar_on_left_p) ?
- !window_is_leftmost (w) :
- !window_is_rightmost (w)));
-#else
- return !window_is_leftmost (w);
-#endif /* HAVE_SCROLLBARS */
+ return !window_is_rightmost (w);
}
int
@@ -1033,72 +1026,40 @@
return other_height;
}
-static int
-window_left_right_gutter_width_internal (struct window *w, int modeline)
-{
- struct frame *f = XFRAME (w->frame);
- int scrollbar_width = window_scrollbar_width (w);
-
- if (!NILP (w->hchild) || !NILP (w->vchild))
- return 0;
-
- if (!modeline)
- {
- if (scrollbar_width)
- return scrollbar_width;
- else if (window_needs_vertical_divider (w))
- return FRAMEMETH (f, divider_width, ());
- else
- return 0;
- }
- else
- {
- /* The shadows on the 3D modelines provide a visual break
- between the modelines of horizontally split windows. 2D
- modelines need some help, though. */
- if (!EQ (Qzero, w->modeline_shadow_thickness))
- return 0;
- else if (window_needs_vertical_divider (w))
- return FRAMEMETH (f, divider_width, ());
- else
- return 0;
- }
-}
-
int
window_left_gutter_width (struct window *w, int modeline)
{
+ int gutter = window_left_toolbar_width (w);
+
if (!NILP (w->hchild) || !NILP (w->vchild))
return 0;
+
#ifdef HAVE_SCROLLBARS
- if (!NILP (w->scrollbar_on_left_p))
- {
-#endif
- return (window_left_right_gutter_width_internal (w, modeline) +
- window_left_toolbar_width (w));
-#ifdef HAVE_SCROLLBARS
- }
- else
- return window_left_toolbar_width (w);
+ if (!modeline && !NILP (w->scrollbar_on_left_p))
+ gutter += window_scrollbar_width (w);
#endif
+
+ return gutter;
}
int
window_right_gutter_width (struct window *w, int modeline)
{
+ int gutter = window_left_toolbar_width (w);
+
if (!NILP (w->hchild) || !NILP (w->vchild))
return 0;
#ifdef HAVE_SCROLLBARS
- if (NILP (w->scrollbar_on_left_p))
- {
- return (window_left_right_gutter_width_internal (w, modeline) +
- window_right_toolbar_width (w));
- }
- else
+ if (!modeline && NILP (w->scrollbar_on_left_p))
+ gutter += window_scrollbar_width (w);
#endif
- return window_right_toolbar_width (w);
+
+ if (window_needs_vertical_divider (w))
+ gutter += FRAMEMETH (XFRAME (WINDOW_FRAME (w)), divider_width, ());
+
+ return gutter;
}
Index: lisp/glyphs.el
===================================================================
RCS file: /var/cvsroot/ntxemacs/lisp/glyphs.el,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 glyphs.el
--- lisp/glyphs.el 1998/04/05 13:03:48 1.1.1.2
+++ lisp/glyphs.el 1998/05/11 15:38:06
@@ -511,6 +511,12 @@
If unspecified in a particular domain, `nontext-pointer-glyph' is used.")
(set-glyph-face toolbar-pointer-glyph 'pointer)
+(defvar divider-pointer-glyph (make-pointer-glyph)
+ "*The shape of the mouse-pointer when over a window divider.
+This is a glyph; use `set-glyph-image' to change it.
+If unspecified in a particular domain, `nontext-pointer-glyph' is used.")
+(set-glyph-face divider-pointer-glyph 'pointer)
+
;; The following three are in C.
(if (featurep 'menubar)
(set-glyph-face menubar-pointer-glyph 'pointer))
@@ -546,6 +552,7 @@
(define-constant-glyph 'selection-pointer-glyph)
(define-constant-glyph 'busy-pointer-glyph)
(define-constant-glyph 'gc-pointer-glyph)
+(define-constant-glyph 'divider-pointer-glyph)
(define-constant-glyph 'toolbar-pointer-glyph)
(define-constant-glyph 'menubar-pointer-glyph)
(define-constant-glyph 'scrollbar-pointer-glyph)
Index: lisp/mouse.el
===================================================================
RCS file: /var/cvsroot/ntxemacs/lisp/mouse.el,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 mouse.el
--- lisp/mouse.el 1998/05/10 12:59:11 1.1.1.7
+++ lisp/mouse.el 1998/05/11 15:40:25
@@ -1337,6 +1337,9 @@
((event-over-modeline-p event)
'(modeline-pointer-glyph nontext-pointer-glyph
text-pointer-glyph))
+ ((event-over-divider-p event)
+ '(divider-pointer-glyph nontext-pointer-glyph
+ text-pointer-glyph))
(point '(text-pointer-glyph))
(buffer '(nontext-pointer-glyph text-pointer-glyph))
(t '(nontext-pointer-glyph text-pointer-glyph))))
@@ -1399,5 +1402,100 @@
nil)
(setq mouse-motion-handler 'default-mouse-motion-handler)
+
+;;
+;; Vertical divider dragging
+;;
+(defun drag-window-divider (event)
+ "Handle resizing windows by dragging window dividers.
+This is an intenal function, normally bound to button1 event in
+window-divider-map. You would not call it, but you may bind it to
+other mouse buttons."
+ (interactive "e")
+ (let ((window (event-window event))
+ (frame (event-channel event))
+ (last-timestamp (event-timestamp event))
+ (doit t))
+
+ (while doit
+ (let ((old-right (caddr (window-pixel-edges window)))
+ (old-left (car (window-pixel-edges window)))
+ (backup-conf (current-window-configuration frame))
+ (old-edges-all-windows (mapcar 'window-pixel-edges (window-list))))
+
+ ;; This is borrowed from modeline.el:
+ ;; requeue event and quit if this is a misc-user, eval or
+ ;; keypress event.
+ ;; quit if this is a button press or release event, or if the event
+ ;; occurred in some other frame.
+ ;; drag if this is a mouse motion event and the time
+ ;; between this event and the last event is greater than
+ ;; drag-modeline-event-lag.
+ ;; do nothing if this is any other kind of event.
+ (setq event (next-event event))
+ (cond ((or (misc-user-event-p event)
+ (key-press-event-p event))
+ (setq unread-command-events (nconc unread-command-events
+ (list event))
+ doit nil))
+ ((button-release-event-p event)
+ (setq doit nil))
+ ((button-event-p event)
+ (setq done nil))
+ ((not (motion-event-p event))
+ (dispatch-event event))
+ ((not (eq frame (event-frame event)))
+ (setq done nil))
+ ((< (abs (- (event-timestamp event) last-timestamp))
+ drag-modeline-event-lag))
+ (t
+ (setq last-timestamp (event-timestamp event))
+ ;; Enlarge the window, calculating change in characters
+ ;; of default font. Do not let the window to become
+ ;; less than alolwed minimum (not because that's critical
+ ;; for the code performance, just the visual effect is
+ ;; better: when cursor goes to the left of the next left
+ ;; divider, the vindow being resized shrinks to minimal
+ ;; size.
+ (enlarge-window (max (- window-min-width (window-width window))
+ (/ (- (event-x-pixel event) old-right)
+ (face-width 'default window)))
+ t window)
+ ;; Backout the change if some windows got deleted, or
+ ;; if the change caused more than two windows to resize
+ ;; (shifting the whole stack right is ugly), or if the
+ ;; left window side has slipped (right side cannot be
+ ;; moved any funrther to the right, so enlarge-window
+ ;; plays bad games with the left edge.
+ (if (or (/= (count-windows) (length old-edges-all-windows))
+ (/= old-left (car (window-pixel-edges window)))
+ ;; This check is very hairy. We allow any number
+ ;; of left edges to change, but only to the same
+ ;; new value. Similar procedure is for the right edges.
+ (let ((all-that-bad nil)
+ (new-left-ok nil)
+ (new-right-ok nil))
+ (mapcar* (lambda (window old-edges)
+ (let ((new (car (window-pixel-edges window))))
+ (if (/= new (car old-edges))
+ (if (and new-left-ok
+ (/= new-left-ok new))
+ (setq all-that-bad t)
+ (setq new-left-ok new)))))
+ (window-list) old-edges-all-windows)
+ (mapcar* (lambda (window old-edges)
+ (let ((new (caddr (window-pixel-edges window))))
+ (if (/= new (caddr old-edges))
+ (if (and new-right-ok
+ (/= new-right-ok new))
+ (setq all-that-bad t)
+ (setq new-right-ok new)))))
+ (window-list) old-edges-all-windows)
+ all-that-bad))
+ (set-window-configuration backup-conf))))
+ ))))
+
+(setq window-divider-map (make-keymap))
+(define-key window-divider-map 'button1 'drag-window-divider)
;;; mouse.el ends here
Index: lisp/x-mouse.el
===================================================================
RCS file: /var/cvsroot/ntxemacs/lisp/x-mouse.el,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 x-mouse.el
--- lisp/x-mouse.el 1998/04/05 13:04:30 1.1.1.4
+++ lisp/x-mouse.el 1998/05/11 15:39:33
@@ -165,6 +165,9 @@
(set-glyph-image toolbar-pointer-glyph
(or (x-get-resource "toolBarPointer" "Cursor" 'string device)
"left_ptr"))
+ (set-glyph-image divider-pointer-glyph
+ (or (x-get-resource "dividerPointer" "Cursor" 'string device)
+ "sb_h_double_arrow"))
(let ((fg
(x-get-resource "pointerColor" "Foreground" 'string
device)))
(and fg