Here is what I've done so far. The idea was to create a general
x_scrollbar_size_changed_in_frame_1() function, and make it do all the
usual stunts, except for one: when scrollbar is supposed to be
invisible, pretend that the size is 0.
>From the user's perspective, this means that setting
vertical-scrollbar-visible-p to nil turns it off. However,
(specifier-instance scrollbar-width) would still return 15 or
whatever. For horizontal scrollbar, having
horizontal-scrollbar-visible-p to nil means that the scrollbar is not
there. Having it t means that the scrollbar *might* be there,
depending on truncate-lines and whatnot.
However, for some reason, this is not working. I assume that the
problem is with the geometry calculations. I'm not sure.
Anyway, here is the patch I've come up with. I'll keep hacking on
this, but if someone has an idea, I'll appreciate it...
1998-05-04 Hrvoje Niksic <hniksic(a)srce.hr>
* scrollbar.c (vertical_scrollbar_visible_p_changed_in_frame): New
function.
(horizontal_scrollbar_visible_p_changed_in_frame): Ditto.
* window.h (struct window): Ditto.
* frameslots.h: New slots.
* scrollbar.c (specifier_vars_of_scrollbar): New specifiers
horizontal-scrollbar-visible-p and vertical-scrollbar-visible-p.
* scrollbar-x.c (x_scrollbar_size_changed_in_frame_1): New
function.
(x_scrollbar_width_changed_in_frame): Use it.
(x_scrollbar_height_changed_in_frame): Ditto.
* toolbar-x.c (x_toolbar_size_changed_in_frame_1): Use the cached
value instead of checking through Fspecifier_instance.
--- src/scrollbar.c.orig Mon May 4 03:04:59 1998
+++ src/scrollbar.c Mon May 4 04:16:39 1998
@@ -63,6 +63,8 @@
/* Height of the scrollbar. */
Lisp_Object Vscrollbar_height;
+Lisp_Object Vhorizontal_scrollbar_visible_p, Vvertical_scrollbar_visible_p;
+
Lisp_Object Vscrollbar_pointer_glyph;
EXFUN (Fcenter_to_window_line, 2);
@@ -603,6 +605,28 @@
}
/* This function is called as a result of a change to the
+ `vertical-scrollbar-visible-p' specifier. */
+static void
+vertical_scrollbar_visible_p_changed_in_frame (Lisp_Object specifier,
+ struct frame *f,
+ Lisp_Object oldval)
+{
+ MAYBE_FRAMEMETH (f, vertical_scrollbar_visible_p_changed_in_frame,
+ (specifier, f, oldval));
+}
+
+/* This function is called as a result of a change to the
+ `horizontal-scrollbar-visible-p' specifier. */
+static void
+horizontal_scrollbar_visible_p_changed_in_frame (Lisp_Object specifier,
+ struct frame *f,
+ Lisp_Object oldval)
+{
+ MAYBE_FRAMEMETH (f, horizontal_scrollbar_visible_p_changed_in_frame,
+ (specifier, f, oldval));
+}
+
+/* This function is called as a result of a change to the
`scrollbar-pointer' glyph. */
static void
scrollbar_pointer_changed_in_window (Lisp_Object specifier, struct window *w,
@@ -963,6 +987,36 @@
slot_offset (struct frame,
scrollbar_height),
scrollbar_height_changed_in_frame);
+
+ DEFVAR_SPECIFIER ("vertical-scrollbar-visible-p", &Vvertical_scrollbar_visible_p /*
+*Whether vertical scrollbar is visible.
+This is a specifier; use `set-specifier' to change it.
+*/ );
+ Vvertical_scrollbar_visible_p = Fmake_specifier (Qboolean);
+ set_specifier_fallback (Vvertical_scrollbar_visible_p,
+ list1 (Fcons (Qnil, Qt)));
+ set_specifier_caching (Vvertical_scrollbar_visible_p,
+ slot_offset (struct window,
+ vertical_scrollbar_visible_p),
+ some_window_value_changed,
+ slot_offset (struct frame,
+ vertical_scrollbar_visible_p),
+ vertical_scrollbar_visible_p_changed_in_frame);
+
+ DEFVAR_SPECIFIER ("horizontal-scrollbar-visible-p", &Vhorizontal_scrollbar_visible_p /*
+*Whether horizontal scrollbar is visible.
+This is a specifier; use `set-specifier' to change it.
+*/ );
+ Vhorizontal_scrollbar_visible_p = Fmake_specifier (Qboolean);
+ set_specifier_fallback (Vhorizontal_scrollbar_visible_p,
+ list1 (Fcons (Qnil, Qt)));
+ set_specifier_caching (Vhorizontal_scrollbar_visible_p,
+ slot_offset (struct window,
+ horizontal_scrollbar_visible_p),
+ some_window_value_changed,
+ slot_offset (struct frame,
+ horizontal_scrollbar_visible_p),
+ horizontal_scrollbar_visible_p_changed_in_frame);
}
void
--- src/scrollbar-x.c.orig Mon May 4 04:05:56 1998
+++ src/scrollbar-x.c Tue May 5 02:48:14 1998
@@ -294,16 +294,39 @@
}
}
-/* A device method. */
+/* This shares code for changing scrollbar size and visibility. */
static void
-x_scrollbar_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
- Lisp_Object oldval)
+x_scrollbar_size_changed_in_frame_1 (struct frame *f,
+ int verticalp, int change_size_p,
+ Lisp_Object oldval)
{
- XtWidgetGeometry req, repl;
- Lisp_Object newval = f->scrollbar_width;
+ Lisp_Object *sizeptr = (verticalp ?
+ &f->scrollbar_width : &f->scrollbar_height);
+ Lisp_Object newvisiblep = (verticalp ?
+ f->vertical_scrollbar_visible_p
+ : f->horizontal_scrollbar_visible_p);
+ Lisp_Object oldsize, newsize;
+
+ /* If no change is to be done, do nothing. */
+ if ((change_size_p && EQ (oldval, *sizeptr))
+ || (!change_size_p && EQ (oldval, newvisiblep)))
+ return;
in_specifier_change_function++;
+ if (NILP (newvisiblep))
+ newsize = Qzero;
+ else if (!INTP (*sizeptr))
+ /* Happens during initialization. */
+ newsize = Qzero;
+ else
+ newsize = *sizeptr;
+
+ if (change_size_p)
+ oldsize = oldval;
+ else
+ oldsize = NILP (newvisiblep) ? *sizeptr : Qzero;
+
/* We want the text area to stay the same size. So, we query the
current size and then adjust it for the change in the scrollbar
width. */
@@ -311,20 +334,25 @@
/* mirror the value in the frame resources, unless it was already
done. */
if (!in_resource_setting)
- Xt_SET_VALUE (FRAME_X_TEXT_WIDGET (f), XtNscrollBarWidth, XINT (newval));
+ Xt_SET_VALUE (FRAME_X_TEXT_WIDGET (f),
+ verticalp ? XtNscrollBarWidth : XtNscrollBarHeight,
+ XINT (newsize));
if (XtIsRealized (FRAME_X_CONTAINER_WIDGET (f)))
{
+ XtWidgetGeometry req, repl;
req.request_mode = 0;
/* the query-geometry method looks at the current value of
f->scrollbar_width, so temporarily set it back to the old
one. */
- f->scrollbar_width = oldval;
+ if (change_size_p)
+ *sizeptr = oldsize;
XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
- f->scrollbar_width = newval;
+ if (change_size_p)
+ *sizeptr = newsize;
- repl.width += XINT (newval) - XINT (oldval);
+ repl.width += XINT (newsize) - XINT (oldsize);
EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width,
repl.height);
}
@@ -334,43 +362,36 @@
/* A device method. */
static void
+x_scrollbar_width_changed_in_frame (Lisp_Object specifier, struct frame *f,
+ Lisp_Object oldval)
+{
+ x_scrollbar_size_changed_in_frame_1 (f, 1, 1, oldval);
+}
+
+/* A device method. */
+static void
x_scrollbar_height_changed_in_frame (Lisp_Object specifier, struct frame *f,
Lisp_Object oldval)
{
- XtWidgetGeometry req, repl;
- Lisp_Object newval = f->scrollbar_height;
-
- in_specifier_change_function++;
-
- /* We want the text area to stay the same size. So, we query the
- current size and then adjust it for the change in the scrollbar
- height. */
-
- /* mirror the value in the frame resources, unless it was already
- done. Also don't do it if this is the when the frame is being
- created -- the widgets don't even exist yet, and even if they
- did, we wouldn't want to overwrite the resource information
- (which might specify a user preference). */
- if (!in_resource_setting)
- Xt_SET_VALUE (FRAME_X_TEXT_WIDGET (f), XtNscrollBarHeight, XINT (newval));
-
- if (XtIsRealized (FRAME_X_CONTAINER_WIDGET (f)))
- {
- req.request_mode = 0;
-
- /* the query-geometry method looks at the current value of
- f->scrollbar_height, so temporarily set it back to the old
- one. */
- f->scrollbar_height = oldval;
- XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
- f->scrollbar_height = newval;
+ x_scrollbar_size_changed_in_frame_1 (f, 0, 1, oldval);
+}
- repl.height += XINT (newval) - XINT (oldval);
- EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width,
- repl.height);
- }
+/* A device method. */
+static void
+x_vertical_scrollbar_visible_p_changed_in_frame (Lisp_Object specifier,
+ struct frame *f,
+ Lisp_Object oldval)
+{
+ x_scrollbar_size_changed_in_frame_1 (f, 1, 0, oldval);
+}
- in_specifier_change_function--;
+/* A device method. */
+static void
+x_horizontal_scrollbar_visible_p_changed_in_frame (Lisp_Object specifier,
+ struct frame *f,
+ Lisp_Object oldval)
+{
+ x_scrollbar_size_changed_in_frame_1 (f, 0, 0, oldval);
}
enum x_scrollbar_loop
@@ -819,6 +840,8 @@
CONSOLE_HAS_METHOD (x, update_scrollbar_instance_status);
CONSOLE_HAS_METHOD (x, scrollbar_width_changed_in_frame);
CONSOLE_HAS_METHOD (x, scrollbar_height_changed_in_frame);
+ CONSOLE_HAS_METHOD (x, vertical_scrollbar_visible_p_changed_in_frame);
+ CONSOLE_HAS_METHOD (x, horizontal_scrollbar_visible_p_changed_in_frame);
CONSOLE_HAS_METHOD (x, scrollbar_pointer_changed_in_window);
#ifdef MEMORY_USAGE_STATS
CONSOLE_HAS_METHOD (x, compute_scrollbar_instance_usage);
--- src/frameslots.h.orig Mon May 4 03:33:50 1998
+++ src/frameslots.h Mon May 4 03:34:14 1998
@@ -99,9 +99,12 @@
#endif
#ifdef HAVE_SCROLLBARS
- /* Width and height of the scrollbars. */
+ /* Size and visibility of the scrollbars. */
MARKED_SLOT (scrollbar_width);
MARKED_SLOT (scrollbar_height);
+
+ MARKED_SLOT (vertical_scrollbar_visible_p);
+ MARKED_SLOT (horizontal_scrollbar_visible_p);
#endif
#ifdef HAVE_TOOLBARS
--- src/window.h.orig Mon May 4 03:34:23 1998
+++ src/window.h Mon May 4 03:34:58 1998
@@ -194,6 +194,9 @@
Lisp_Object scrollbar_width;
/* Height of horizontal scrollbars. */
Lisp_Object scrollbar_height;
+ /* Visibility of scrollbars. */
+ Lisp_Object vertical_scrollbar_visible_p;
+ Lisp_Object horizontal_scrollbar_visible_p;
/* Pointer to use for vertical and horizontal scrollbars. */
Lisp_Object scrollbar_pointer;
#endif /* HAVE_SCROLLBARS */
--
Hrvoje Niksic <hniksic(a)srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
Try to use "ad nauseam" at least once per flame. It doesn't mean
anything; but it gives that polished feel to your postings.