Subject: 24.0.50; frame position calculation with vertical tool bar (Gtk+)

From: Stephen Berman <[email-masked]>
Date: Thu, 16 Sep 2010 22:00:08 +0200

1. emacs -Q
2. Click menu Options->Show/Hide->Tool-bar->On the left (or: ->On the
   right, it doesn't matter which).
3. Move the frame to the left edge of the monitor display.
4. M-x speedbar
=> The speedbar frame opens overlapping the right side of the main frame
by the width of the vertical tool bar.

The reason for the overlap is that only frame-pixel-width is used (in
dframe-reposition-frame-emacs) to calculate the width, but this does not
take the tool bar into account.  That's innocuous with the default
horizontal tool bar, but not when it's placed vertically.  AFAICT there
is no easy way in Lisp to get this number (you can calculate it using
the (fullscreen . fullwidth) frame parameter with and without a vertical
tool bar, but it would be absurd to do that in the middle of a program).
But it seems straightforward to expose the value of FRAME_TOOLBAR_WIDTH
to Lisp, following the example of frame-pixel-width.  The attached patch
does this (I did not bother to implement a wrapper like x_pixel_width in
Fframe_pixel_width, since I don't see an additional use for it in the
case of the tool bar width).  This can then be used to make the correct
frame repositioning in dframe-reposition-frame-emacs, as in the attached
patch (I also increased the space on the right from 5 to 10 pixels, to
make it the same as the space on the left; alternatively, both could be
5 pixels, which on my system appears to leave no space between the two
frames).  (This fixes the frame repositioning for the default value
'left-right of speedbar-default-position.  I think there may be problems
with the value 'left or 'right when the parent frame is too close to the
display edge, but perhaps that can be regarded as a poor choice by the
user, so I didn't bother with it.)

In GNU Emacs 24.0.50.7 (i686-pc-linux-gnu, GTK+ Version 2.18.6)
 of 2010-09-16 on escher
Windowing system distributor `The X.Org Foundation', version 11.0.10605000
configured using `configure  '--with-imagemagick' '--without-toolkit-scroll-bars''

=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog	2010-09-15 15:30:43 +0000
+++ lisp/ChangeLog	2010-09-16 18:08:37 +0000
@@ -1,3 +1,9 @@
+2010-09-16  Stephen Berman  <[email-masked]>
+
+	* dframe.el (dframe-reposition-frame-emacs): Use tool-bar-pixel-width
+	in calculating new frame position.  Add more space between new and
+	parent on the left.
+
 2010-09-15  Stefan Monnier  <[email-masked]>
 
 	* emacs-lisp/bytecomp.el (byte-compile-warning-types): New type

=== modified file 'lisp/dframe.el'
--- lisp/dframe.el	2010-01-13 08:35:10 +0000
+++ lisp/dframe.el	2010-09-16 17:01:33 +0000
@@ -430,7 +430,8 @@
   (unless (or (not window-system) (eq window-system 'pc))
     (let* ((pfx (dframe-frame-parameter parent-frame 'left))
 	   (pfy (dframe-frame-parameter parent-frame 'top))
-	   (pfw (frame-pixel-width parent-frame))
+	   (pfw (+ (tool-bar-pixel-width parent-frame)
+		   (frame-pixel-width parent-frame)))
 	   (pfh (frame-pixel-height parent-frame))
 	   (nfw (frame-pixel-width new-frame))
 	   (nfh (frame-pixel-height new-frame))
@@ -459,7 +460,7 @@
 		      (- (x-display-pixel-height) (car (cdr pfy)) pfh)
 		    (car (cdr pfy)))))
       (cond ((eq location 'right)
-	     (setq newleft (+ pfx pfw 5)
+	     (setq newleft (+ pfx pfw 10)
 		   newtop pfy))
 	    ((eq location 'left)
 	     (setq newleft (- pfx 10 nfw)
@@ -471,7 +472,7 @@
 		   ;; extra 10 is just dressings for window
 		   ;; decorations.
 		   (let* ((left-guess (- pfx 10 nfw))
-			  (right-guess (+ pfx pfw 5))
+			  (right-guess (+ pfx pfw 10))
 			  (left-margin left-guess)
 			  (right-margin (- (x-display-pixel-width)
 					   right-guess 5 nfw)))

=== modified file 'src/ChangeLog'
--- src/ChangeLog	2010-09-14 20:32:35 +0000
+++ src/ChangeLog	2010-09-16 18:02:53 +0000
@@ -1,3 +1,8 @@
+2010-09-16  Stephen Berman  <[email-masked]>
+
+	* frame.c (Ftool_bar_pixel_width): New function to expose tool
+	bar's pixel width to Lisp.
+
 2010-09-14  Juanma Barranquero  <[email-masked]>
 
 	* cmds.c (syms_of_cmds) <post-self-insert-hook>: Fix typos in docstring.

=== modified file 'src/frame.c'
--- src/frame.c	2010-08-08 21:03:45 +0000
+++ src/frame.c	2010-09-16 12:22:21 +0000
@@ -2649,6 +2649,29 @@
 #endif
     return make_number (FRAME_COLS (f));
 }
+
+DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width,
+       Stool_bar_pixel_width, 0, 1, 0,
+       doc: /* Return width in pixels of FRAME's tool bar.
+The result is greater than zero only when the tool bar is on the left
+or right side of FRAME.  If FRAME is omitted, the selected frame is
+used.  */)
+  (Lisp_Object frame)
+{
+  struct frame *f;
+
+  if (NILP (frame))
+    frame = selected_frame;
+  CHECK_FRAME (frame);
+  f = XFRAME (frame);
+
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
+    return make_number (FRAME_TOOLBAR_WIDTH (f));
+  else
+#endif
+    return 0;
+}
 
 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
        doc: /* Specify that the frame FRAME has LINES lines.
@@ -4596,6 +4619,7 @@
   defsubr (&Sframe_char_width);
   defsubr (&Sframe_pixel_height);
   defsubr (&Sframe_pixel_width);
+  defsubr (&Stool_bar_pixel_width);
   defsubr (&Sset_frame_height);
   defsubr (&Sset_frame_width);
   defsubr (&Sset_frame_size);