# HG changeset patch # User Jan D. # Date 1280422199 -7200 # Node ID 06384b3caebf00c651b208a62cb1823b7ce15b2c # Parent 3021343b766a992ed909158c11ccd06a24c61cdd Add ability to put Gtk+ tool bar on the left/right/bottom or top. Default top. * lisp/menu-bar.el (menu-bar-showhide-tool-bar-menu-customize-enable-left) (menu-bar-showhide-tool-bar-menu-customize-disable) (menu-bar-showhide-tool-bar-menu-customize-enable-right) (menu-bar-showhide-tool-bar-menu-customize-enable-top) (menu-bar-showhide-tool-bar-menu-customize-enable-bottom): New functions (menu-bar-showhide-tool-bar-menu): If tool bar is moveable, make a menu for Options => toolbar that can move it. * src/frame.c (Qtool_bar_position): New variable. (make_frame): Set tool_bar_position to Qtop. (frame_parms): Add tool-bar-position. (x_report_frame_params): Store tool_bar_position. (x_set_fringe_width): Reset wm size hint after fringe changes. * src/frame.h (struct frame): Add tool_bar_position. (Qbottom): Declare. * src/gtkutil.c (FRAME_TOTAL_PIXEL_WIDTH): New macro. (xg_frame_set_char_size): Add FRAME_TOOLBAR_WIDTH to pixelwidth. (xg_height_or_width_changed): Use FRAME_TOTAL_PIXEL_WIDTH. (xg_create_frame_widgets): Create a hobox for placing widgets vertically. Use gtk_box_pack_start. (xg_height_or_width_changed): Renamed from xg_height_changed. (x_wm_set_size_hint): Add FRAME_TOOLBAR_WIDTH to base_width. (xg_update_frame_menubar, free_frame_menubar): Change to xg_height_or_width_changed. (xg_tool_bar_detach_callback): Update left/right/top/bottom tool bar size correctly. Remove hardcoded 4, instead use handlebox size - toolbar size. (xg_tool_bar_attach_callback): Update left/right/top/bottom tool bar size correctly. Use handlebox size + toolbar size as additional size. (xg_pack_tool_bar): POS is a new parameter. Set orientation of tool bar based on pos. Only make handlebox_widget if NULL. Check if tool bar goes to vbox or hbox depending on pos. (xg_update_tool_bar_sizes): New function. (update_frame_tool_bar): Remove old_req, new_req. Do not get tool bar height, call xg_update_tool_bar_sizes instead. (free_frame_tool_bar): Remove from hbox or vbox depending on toolbar_in_hbox, Set all FRAME_TOOLBAR_*_(WIDTH|HEIGHT) to zero. (xg_change_toolbar_position): New function. * src/gtkutil.h (xg_change_toolbar_position): Declare. * src/window.c (calc_absolute_offset): Check for FRAME_TOOLBAR_TOP_HEIGHT and FRAME_TOOLBAR_LEFT_WIDTH. * src/xfns.c (x_set_tool_bar_position): New function. (xic_set_statusarea): Use FRAME_TOOLBAR_TOP_HEIGHT. (x_frame_parm_handlers): Add x_set_tool_bar_position. (syms_of_xfns): if USE_GTK, provide move-toolbar. * src/xterm.c (x_set_window_size_1): Add FRAME_TOOLBAR_WIDTH to pixelwidth. * src/xterm.h (struct x_output): Add toolbar_top_height, toolbar_bottom_height, toolbar_left_width, toolbar_right_width. Remove toolbar_height. if USE_GTK: Add hbox_widget and toolbar_in_hbox. (FRAME_TOOLBAR_TOP_HEIGHT, FRAME_TOOLBAR_BOTTOM_HEIGHT) (FRAME_TOOLBAR_LEFT_WIDTH, FRAME_TOOLBAR_RIGHT_WIDTH): New macros. (FRAME_TOOLBAR_HEIGHT): Is now TOP_HEIGHT + BOTTOM_HEIGHT. diff -r 3021343b766a -r 06384b3caebf lisp/ChangeLog --- a/lisp/ChangeLog Thu Jul 29 12:01:14 2010 -0400 +++ b/lisp/ChangeLog Thu Jul 29 18:49:59 2010 +0200 @@ -1,3 +1,13 @@ +2010-07-29 Jan Djärv + + * menu-bar.el (menu-bar-showhide-tool-bar-menu-customize-enable-left) + (menu-bar-showhide-tool-bar-menu-customize-disable) + (menu-bar-showhide-tool-bar-menu-customize-enable-right) + (menu-bar-showhide-tool-bar-menu-customize-enable-top) + (menu-bar-showhide-tool-bar-menu-customize-enable-bottom): New functions + (menu-bar-showhide-tool-bar-menu): If tool bar is moveable, + make a menu for Options => toolbar that can move it. + 2010-07-29 Chong Yidong * emacs-lisp/package-x.el (package--make-rss-entry): diff -r 3021343b766a -r 06384b3caebf lisp/menu-bar.el --- a/lisp/menu-bar.el Thu Jul 29 12:01:14 2010 -0400 +++ b/lisp/menu-bar.el Thu Jul 29 18:49:59 2010 +0200 @@ -968,11 +968,95 @@ :help ,(purecopy "Turn menu-bar on/off") :button (:toggle . (> (frame-parameter nil 'menu-bar-lines) 0)))) -(define-key menu-bar-showhide-menu [showhide-tool-bar] - `(menu-item ,(purecopy "Tool-bar") toggle-tool-bar-mode-from-frame - :help ,(purecopy "Turn tool-bar on/off") - :visible (display-graphic-p) - :button (:toggle . (> (frame-parameter nil 'tool-bar-lines) 0)))) +(defun menu-bar-showhide-tool-bar-menu-customize-disable () + "Do not display tool bars." + (interactive) + (customize-set-variable 'tool-bar-mode nil)) +(defun menu-bar-showhide-tool-bar-menu-customize-enable-left () + "Display tool bars on the left side." + (interactive) + (customize-set-variable 'tool-bar-mode t) + (set-frame-parameter nil 'tool-bar-position 'left)) + +(defun menu-bar-showhide-tool-bar-menu-customize-enable-right () + "Display tool bars on the right side." + (interactive) + (customize-set-variable 'tool-bar-mode t) + (set-frame-parameter nil 'tool-bar-position 'right)) +(defun menu-bar-showhide-tool-bar-menu-customize-enable-top () + "Display tool bars on the top side." + (interactive) + (customize-set-variable 'tool-bar-mode t) + (set-frame-parameter nil 'tool-bar-position 'top)) +(defun menu-bar-showhide-tool-bar-menu-customize-enable-bottom () + "Display tool bars on the bottom side." + (interactive) + (customize-set-variable 'tool-bar-mode t) + (set-frame-parameter nil 'tool-bar-position 'bottom)) + +(if (featurep 'move-toolbar) + (progn + (defvar menu-bar-showhide-tool-bar-menu (make-sparse-keymap "Tool-bar")) + + (define-key menu-bar-showhide-tool-bar-menu [showhide-tool-bar-left] + `(menu-item ,(purecopy "On the left") + menu-bar-showhide-tool-bar-menu-customize-enable-left + :help ,(purecopy "Tool-bar at the left side") + :visible (display-graphic-p) + :button + (:radio . (and tool-bar-mode + (eq (frame-parameter nil 'tool-bar-position) + 'left))))) + + (define-key menu-bar-showhide-tool-bar-menu [showhide-tool-bar-right] + `(menu-item ,(purecopy "On the right") + menu-bar-showhide-tool-bar-menu-customize-enable-right + :help ,(purecopy "Tool-bar at the right side") + :visible (display-graphic-p) + :button + (:radio . (and tool-bar-mode + (eq (frame-parameter nil 'tool-bar-position) + 'right))))) + + (define-key menu-bar-showhide-tool-bar-menu [showhide-tool-bar-bottom] + `(menu-item ,(purecopy "On the bottom") + menu-bar-showhide-tool-bar-menu-customize-enable-bottom + :help ,(purecopy "Tool-bar at the bottom") + :visible (display-graphic-p) + :button + (:radio . (and tool-bar-mode + (eq (frame-parameter nil 'tool-bar-position) + 'bottom))))) + + (define-key menu-bar-showhide-tool-bar-menu [showhide-tool-bar-top] + `(menu-item ,(purecopy "On the top") + menu-bar-showhide-tool-bar-menu-customize-enable-top + :help ,(purecopy "Tool-bar at the top") + :visible (display-graphic-p) + :button + (:radio . (and tool-bar-mode + (eq (frame-parameter nil 'tool-bar-position) + 'top))))) + + (define-key menu-bar-showhide-tool-bar-menu [showhide-tool-bar-none] + `(menu-item ,(purecopy "None") + menu-bar-showhide-tool-bar-menu-customize-disable + :help ,(purecopy "Turn tool-bar off") + :visible (display-graphic-p) + :button (:radio . (eq tool-bar-mode nil)))) + + (define-key menu-bar-showhide-menu [showhide-tool-bar] + `(menu-item ,(purecopy "Tool-bar") ,menu-bar-showhide-tool-bar-menu + :visible (display-graphic-p))) + + ) + ;; else not tool bar that can move. + (define-key menu-bar-showhide-menu [showhide-tool-bar] + `(menu-item ,(purecopy "Tool-bar") toggle-tool-bar-mode-from-frame + :help ,(purecopy "Turn tool-bar on/off") + :visible (display-graphic-p) + :button (:toggle . (> (frame-parameter nil 'tool-bar-lines) 0)))) +) (define-key menu-bar-options-menu [showhide] `(menu-item ,(purecopy "Show/Hide") ,menu-bar-showhide-menu)) diff -r 3021343b766a -r 06384b3caebf src/ChangeLog --- a/src/ChangeLog Thu Jul 29 12:01:14 2010 -0400 +++ b/src/ChangeLog Thu Jul 29 18:49:59 2010 +0200 @@ -1,3 +1,60 @@ +2010-07-29 Jan Djärv + + * xterm.h (struct x_output): Add toolbar_top_height, + toolbar_bottom_height, toolbar_left_width, toolbar_right_width. Remove + toolbar_height. + if USE_GTK: Add hbox_widget and toolbar_in_hbox. + (FRAME_TOOLBAR_TOP_HEIGHT, FRAME_TOOLBAR_BOTTOM_HEIGHT) + (FRAME_TOOLBAR_LEFT_WIDTH, FRAME_TOOLBAR_RIGHT_WIDTH): New macros. + (FRAME_TOOLBAR_HEIGHT): Is now TOP_HEIGHT + BOTTOM_HEIGHT. + + * xterm.c (x_set_window_size_1): Add FRAME_TOOLBAR_WIDTH to pixelwidth. + + * xfns.c (x_set_tool_bar_position): New function. + (xic_set_statusarea): Use FRAME_TOOLBAR_TOP_HEIGHT. + (x_frame_parm_handlers): Add x_set_tool_bar_position. + (syms_of_xfns): if USE_GTK, provide move-toolbar. + + * window.c (calc_absolute_offset): Check for FRAME_TOOLBAR_TOP_HEIGHT + and FRAME_TOOLBAR_LEFT_WIDTH. + + * gtkutil.h (xg_change_toolbar_position): Declare. + + * gtkutil.c (FRAME_TOTAL_PIXEL_WIDTH): New macro. + (xg_frame_set_char_size): Add FRAME_TOOLBAR_WIDTH to pixelwidth. + (xg_height_or_width_changed): Use FRAME_TOTAL_PIXEL_WIDTH. + (xg_create_frame_widgets): Create a hobox for placing widgets + vertically. Use gtk_box_pack_start. + (xg_height_or_width_changed): Renamed from xg_height_changed. + (x_wm_set_size_hint): Add FRAME_TOOLBAR_WIDTH to base_width. + (xg_update_frame_menubar, free_frame_menubar): Change to + xg_height_or_width_changed. + (xg_tool_bar_detach_callback): Update left/right/top/bottom tool bar + size correctly. Remove hardcoded 4, instead use handlebox size - + toolbar size. + (xg_tool_bar_attach_callback): Update left/right/top/bottom tool bar + size correctly. Use handlebox size + toolbar size as additional + size. + (xg_pack_tool_bar): POS is a new parameter. + Set orientation of tool bar based on pos. + Only make handlebox_widget if NULL. + Check if tool bar goes to vbox or hbox depending on pos. + (xg_update_tool_bar_sizes): New function. + (update_frame_tool_bar): Remove old_req, new_req. Do not get tool bar + height, call xg_update_tool_bar_sizes instead. + (free_frame_tool_bar): Remove from hbox or vbox depending on + toolbar_in_hbox, Set all FRAME_TOOLBAR_*_(WIDTH|HEIGHT) to zero. + (xg_change_toolbar_position): New function. + + * frame.h (struct frame): Add tool_bar_position. + (Qbottom): Declare. + + * frame.c (Qtool_bar_position): New variable. + (make_frame): Set tool_bar_position to Qtop. + (frame_parms): Add tool-bar-position. + (x_report_frame_params): Store tool_bar_position. + (x_set_fringe_width): Reset wm size hint after fringe changes. + 2010-07-29 Dan Nicolaescu Make lisp_time_argument declaration work on all systems. diff -r 3021343b766a -r 06384b3caebf src/frame.c --- a/src/frame.c Thu Jul 29 12:01:14 2010 -0400 +++ b/src/frame.c Thu Jul 29 18:49:59 2010 +0200 @@ -119,7 +119,7 @@ Lisp_Object Qtitle, Qname; Lisp_Object Qexplicit_name; Lisp_Object Qunsplittable; -Lisp_Object Qmenu_bar_lines, Qtool_bar_lines; +Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position; Lisp_Object Vmenu_bar_mode, Vtool_bar_mode; Lisp_Object Qleft_fringe, Qright_fringe; Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list; @@ -323,6 +323,7 @@ f->menu_bar_window = Qnil; f->tool_bar_window = Qnil; f->tool_bar_items = Qnil; + f->tool_bar_position = Qtop; f->desired_tool_bar_string = f->current_tool_bar_string = Qnil; f->n_tool_bar_items = 0; f->left_fringe_width = f->right_fringe_width = 0; @@ -2816,6 +2817,7 @@ {"font-backend", &Qfont_backend}, {"alpha", &Qalpha}, {"sticky", &Qsticky}, + {"tool-bar-position", &Qtool_bar_position}, }; #ifdef HAVE_WINDOW_SYSTEM @@ -3209,6 +3211,7 @@ XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc); store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil)); store_in_alist (alistptr, Qparent_id, tem); + store_in_alist (alistptr, Qtool_bar_position, f->tool_bar_position); } @@ -3441,6 +3444,11 @@ x_set_fringe_width (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) { compute_fringe_widths (f, 1); +#ifdef HAVE_X_WINDOWS + /* Must adjust this so window managers report correct number of columns. */ + if (FRAME_X_WINDOW (f) != 0) + x_wm_set_size_hint (f, 0, 0); +#endif } void diff -r 3021343b766a -r 06384b3caebf src/frame.h --- a/src/frame.h Thu Jul 29 12:01:14 2010 -0400 +++ b/src/frame.h Thu Jul 29 18:49:59 2010 +0200 @@ -191,6 +191,10 @@ /* Desired and current tool-bar items. */ Lisp_Object tool_bar_items; + /* Where tool bar is, can be left, right, top or bottom. The native + tool bar only supports top. */ + Lisp_Object tool_bar_position; + /* Desired and current contents displayed in tool_bar_window. */ Lisp_Object desired_tool_bar_string, current_tool_bar_string; @@ -1071,7 +1075,7 @@ extern Lisp_Object Qx_resource_name; -extern Lisp_Object Qleft, Qright, Qtop, Qbox; +extern Lisp_Object Qleft, Qright, Qtop, Qbox, Qbottom; extern Lisp_Object Qdisplay; #ifdef HAVE_WINDOW_SYSTEM diff -r 3021343b766a -r 06384b3caebf src/gtkutil.c --- a/src/gtkutil.c Thu Jul 29 12:01:14 2010 -0400 +++ b/src/gtkutil.c Thu Jul 29 18:49:59 2010 +0200 @@ -44,6 +44,9 @@ #define FRAME_TOTAL_PIXEL_HEIGHT(f) \ (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) +#define FRAME_TOTAL_PIXEL_WIDTH(f) \ + (FRAME_PIXEL_WIDTH (f) + FRAME_TOOLBAR_WIDTH (f)) + /* Avoid "differ in sign" warnings */ #define SSDATA(x) ((char *) SDATA (x)) @@ -640,7 +643,8 @@ /* FRAME_TEXT_COLS_TO_PIXEL_WIDTH uses scroll_bar_actual_width, so call it after calculating that value. */ - pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols); + pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols) + + FRAME_TOOLBAR_WIDTH (f); /* Do this before resize, as we don't know yet if we will be resized. */ @@ -677,14 +681,15 @@ } } -/* Handle height changes (i.e. add/remove menu/toolbar). +/* Handle height/width changes (i.e. add/remove/move menu/toolbar). The policy is to keep the number of editable lines. */ static void -xg_height_changed (FRAME_PTR f) +xg_height_or_width_changed (FRAME_PTR f) { gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), - FRAME_PIXEL_WIDTH (f), FRAME_TOTAL_PIXEL_HEIGHT (f)); + FRAME_TOTAL_PIXEL_WIDTH (f), + FRAME_TOTAL_PIXEL_HEIGHT (f)); f->output_data.x->hint_flags = 0; x_wm_set_size_hint (f, 0, 0); } @@ -733,7 +738,7 @@ xg_create_frame_widgets (FRAME_PTR f) { GtkWidget *wtop; - GtkWidget *wvbox; + GtkWidget *wvbox, *whbox; GtkWidget *wfixed; GdkColor bg; GtkRcStyle *style; @@ -749,12 +754,14 @@ xg_set_screen (wtop, f); wvbox = gtk_vbox_new (FALSE, 0); + whbox = gtk_hbox_new (FALSE, 0); wfixed = gtk_fixed_new (); /* Must have this to place scroll bars */ - if (! wtop || ! wvbox || ! wfixed) + if (! wtop || ! wvbox || ! whbox || ! wfixed) { if (wtop) gtk_widget_destroy (wtop); if (wvbox) gtk_widget_destroy (wvbox); + if (whbox) gtk_widget_destroy (whbox); if (wfixed) gtk_widget_destroy (wfixed); UNBLOCK_INPUT; @@ -775,11 +782,13 @@ FRAME_GTK_OUTER_WIDGET (f) = wtop; FRAME_GTK_WIDGET (f) = wfixed; f->output_data.x->vbox_widget = wvbox; + f->output_data.x->hbox_widget = whbox; gtk_widget_set_has_window (wfixed, TRUE); gtk_container_add (GTK_CONTAINER (wtop), wvbox); - gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (wvbox), whbox, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (whbox), wfixed, TRUE, TRUE, 0); if (FRAME_EXTERNAL_TOOL_BAR (f)) update_frame_tool_bar (f); @@ -889,7 +898,7 @@ size_hints.height_inc = FRAME_LINE_HEIGHT (f); hint_flags |= GDK_HINT_BASE_SIZE; - base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); + base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0) + FRAME_TOOLBAR_WIDTH (f); base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); @@ -2828,7 +2837,7 @@ gtk_widget_show_all (x->menubar_widget); gtk_widget_size_request (x->menubar_widget, &req); FRAME_MENUBAR_HEIGHT (f) = req.height; - xg_height_changed (f); + xg_height_or_width_changed (f); UNBLOCK_INPUT; return 1; @@ -2851,7 +2860,7 @@ the container. */ x->menubar_widget = 0; FRAME_MENUBAR_HEIGHT (f) = 0; - xg_height_changed (f); + xg_height_or_width_changed (f); UNBLOCK_INPUT; } } @@ -3548,13 +3557,21 @@ if (f) { + GtkRequisition req, req2; FRAME_X_OUTPUT (f)->toolbar_detached = 1; - - /* When detaching a tool bar, not everything dissapear. There are - a few pixels left that are used to drop the tool bar back into - place. */ - FRAME_TOOLBAR_HEIGHT (f) = 4; - xg_height_changed (f); + gtk_widget_size_request (GTK_WIDGET (wbox), &req); + gtk_widget_size_request (w, &req2); + req.width -= req2.width; + req.height -= req2.height; + if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0) + FRAME_TOOLBAR_TOP_HEIGHT (f) = req.height; + else if (FRAME_TOOLBAR_BOTTOM_HEIGHT (f) != 0) + FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = req.height; + else if (FRAME_TOOLBAR_RIGHT_WIDTH (f) != 0) + FRAME_TOOLBAR_RIGHT_WIDTH (f) = req.width; + else if (FRAME_TOOLBAR_LEFT_WIDTH (f) != 0) + FRAME_TOOLBAR_LEFT_WIDTH (f) = req.width; + xg_height_or_width_changed (f); } } @@ -3575,13 +3592,21 @@ if (f) { - GtkRequisition req; - + GtkRequisition req, req2; FRAME_X_OUTPUT (f)->toolbar_detached = 0; - - gtk_widget_size_request (w, &req); - FRAME_TOOLBAR_HEIGHT (f) = req.height; - xg_height_changed (f); + gtk_widget_size_request (GTK_WIDGET (wbox), &req); + gtk_widget_size_request (w, &req2); + req.width += req2.width; + req.height += req2.height; + if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0) + FRAME_TOOLBAR_TOP_HEIGHT (f) = req.height; + else if (FRAME_TOOLBAR_BOTTOM_HEIGHT (f) != 0) + FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = req.height; + else if (FRAME_TOOLBAR_RIGHT_WIDTH (f) != 0) + FRAME_TOOLBAR_RIGHT_WIDTH (f) = req.width; + else if (FRAME_TOOLBAR_LEFT_WIDTH (f) != 0) + FRAME_TOOLBAR_LEFT_WIDTH (f) = req.width; + xg_height_or_width_changed (f); } } @@ -3656,34 +3681,6 @@ return FALSE; } -/* Attach a tool bar to frame F. */ - -static void -xg_pack_tool_bar (FRAME_PTR f) -{ - struct x_output *x = f->output_data.x; - int vbox_pos = x->menubar_widget ? 1 : 0; - - x->handlebox_widget = gtk_handle_box_new (); - g_signal_connect (G_OBJECT (x->handlebox_widget), "child-detached", - G_CALLBACK (xg_tool_bar_detach_callback), f); - g_signal_connect (G_OBJECT (x->handlebox_widget), "child-attached", - G_CALLBACK (xg_tool_bar_attach_callback), f); - - gtk_container_add (GTK_CONTAINER (x->handlebox_widget), - x->toolbar_widget); - - gtk_box_pack_start (GTK_BOX (x->vbox_widget), x->handlebox_widget, - FALSE, FALSE, 0); - - gtk_box_reorder_child (GTK_BOX (x->vbox_widget), x->handlebox_widget, - vbox_pos); - - gtk_widget_show (x->toolbar_widget); - gtk_widget_show (x->handlebox_widget); -} - -/* Create a tool bar for frame F. */ #ifdef HAVE_GTK_ORIENTABLE_SET_ORIENTATION #define toolbar_set_orientation(w, o) \ gtk_orientable_set_orientation (GTK_ORIENTABLE (w), o) @@ -3692,6 +3689,56 @@ gtk_toolbar_set_orientation (GTK_TOOLBAR (w), o) #endif +/* Attach a tool bar to frame F. */ + +static void +xg_pack_tool_bar (FRAME_PTR f, Lisp_Object pos) +{ + struct x_output *x = f->output_data.x; + int into_hbox = EQ (pos, Qleft) || EQ (pos, Qright); + + toolbar_set_orientation (x->toolbar_widget, + into_hbox + ? GTK_ORIENTATION_VERTICAL + : GTK_ORIENTATION_HORIZONTAL); + if (!x->handlebox_widget) + { + x->handlebox_widget = gtk_handle_box_new (); + g_signal_connect (G_OBJECT (x->handlebox_widget), "child-detached", + G_CALLBACK (xg_tool_bar_detach_callback), f); + g_signal_connect (G_OBJECT (x->handlebox_widget), "child-attached", + G_CALLBACK (xg_tool_bar_attach_callback), f); + gtk_container_add (GTK_CONTAINER (x->handlebox_widget), + x->toolbar_widget); + } + + if (into_hbox) + { + gtk_box_pack_start (GTK_BOX (x->hbox_widget), x->handlebox_widget, + FALSE, FALSE, 0); + + if (EQ (pos, Qleft)) + gtk_box_reorder_child (GTK_BOX (x->hbox_widget), + x->handlebox_widget, + 0); + x->toolbar_in_hbox = 1; + } + else + { + int vbox_pos = x->menubar_widget ? 1 : 0; + gtk_box_pack_start (GTK_BOX (x->vbox_widget), x->handlebox_widget, + FALSE, FALSE, 0); + + if (EQ (pos, Qtop)) + gtk_box_reorder_child (GTK_BOX (x->vbox_widget), + x->handlebox_widget, + vbox_pos); + x->toolbar_in_hbox = 0; + } +} + +/* Create a tool bar for frame F. */ + static void xg_create_tool_bar (FRAME_PTR f) { @@ -3875,6 +3922,50 @@ gtk_widget_show (GTK_WIDGET (ti)); } +static int +xg_update_tool_bar_sizes (FRAME_PTR f) +{ + struct x_output *x = f->output_data.x; + GtkRequisition req; + int nl = 0, nr = 0, nt = 0, nb = 0; + + gtk_widget_size_request (GTK_WIDGET (x->handlebox_widget), &req); + if (x->toolbar_in_hbox) + { + int pos; + gtk_container_child_get (GTK_CONTAINER (x->hbox_widget), + x->handlebox_widget, + "position", &pos, NULL); + if (pos == 0) nl = req.width; + else nr = req.width; + } + else + { + int pos; + gtk_container_child_get (GTK_CONTAINER (x->vbox_widget), + x->handlebox_widget, + "position", &pos, NULL); + if (pos == 0 || (pos == 1 && x->menubar_widget)) nt = req.height; + else nb = req.height; + } + + if (nl != FRAME_TOOLBAR_LEFT_WIDTH (f) + || nr != FRAME_TOOLBAR_RIGHT_WIDTH (f) + || nt != FRAME_TOOLBAR_TOP_HEIGHT (f) + || nb != FRAME_TOOLBAR_BOTTOM_HEIGHT (f)) + { + FRAME_TOOLBAR_RIGHT_WIDTH (f) = FRAME_TOOLBAR_LEFT_WIDTH (f) + = FRAME_TOOLBAR_TOP_HEIGHT (f) = FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = 0; + FRAME_TOOLBAR_LEFT_WIDTH (f) = nl; + FRAME_TOOLBAR_RIGHT_WIDTH (f) = nr; + FRAME_TOOLBAR_TOP_HEIGHT (f) = nt; + FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = nb; + return 1; + } + + return 0; +} + /* Update the tool bar for frame F. Add new buttons and remove old. */ @@ -3884,7 +3975,6 @@ update_frame_tool_bar (FRAME_PTR f) { int i; - GtkRequisition old_req, new_req; struct x_output *x = f->output_data.x; int hmargin = 0, vmargin = 0; GtkToolbar *wtoolbar; @@ -3925,7 +4015,6 @@ xg_create_tool_bar (f); wtoolbar = GTK_TOOLBAR (x->toolbar_widget); - gtk_widget_size_request (GTK_WIDGET (wtoolbar), &old_req); dir = gtk_widget_get_direction (GTK_WIDGET (wtoolbar)); for (i = 0; i < f->n_tool_bar_items; ++i) @@ -4143,18 +4232,16 @@ if (ti) gtk_widget_hide_all (GTK_WIDGET (ti)); } while (ti != NULL); - new_req.height = 0; - if (pack_tool_bar && f->n_tool_bar_items != 0) - xg_pack_tool_bar (f); - - - gtk_widget_size_request (GTK_WIDGET (wtoolbar), &new_req); - if (old_req.height != new_req.height - && ! FRAME_X_OUTPUT (f)->toolbar_detached) + if (f->n_tool_bar_items != 0) { - FRAME_TOOLBAR_HEIGHT (f) = new_req.height; - xg_height_changed (f); + if (pack_tool_bar) + xg_pack_tool_bar (f, f->tool_bar_position); + gtk_widget_show (x->toolbar_widget); + gtk_widget_show (x->handlebox_widget); + if (xg_update_tool_bar_sizes (f)) + xg_height_or_width_changed (f); } + UNBLOCK_INPUT; } @@ -4172,21 +4259,54 @@ BLOCK_INPUT; /* We may have created the toolbar_widget in xg_create_tool_bar, but not the x->handlebox_widget which is created in xg_pack_tool_bar. */ - if (is_packed) - gtk_container_remove (GTK_CONTAINER (x->vbox_widget), - x->handlebox_widget); + if (is_packed) + { + if (x->toolbar_in_hbox) + gtk_container_remove (GTK_CONTAINER (x->hbox_widget), + x->handlebox_widget); + else + gtk_container_remove (GTK_CONTAINER (x->vbox_widget), + x->handlebox_widget); + } else gtk_widget_destroy (x->toolbar_widget); x->toolbar_widget = 0; x->handlebox_widget = 0; - FRAME_TOOLBAR_HEIGHT (f) = 0; - xg_height_changed (f); + FRAME_TOOLBAR_TOP_HEIGHT (f) = FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = 0; + FRAME_TOOLBAR_LEFT_WIDTH (f) = FRAME_TOOLBAR_RIGHT_WIDTH (f) = 0; + + xg_height_or_width_changed (f); UNBLOCK_INPUT; } } +int +xg_change_toolbar_position (FRAME_PTR f, Lisp_Object pos) +{ + struct x_output *x = f->output_data.x; + + if (! x->toolbar_widget || ! x->handlebox_widget) + return 1; + + BLOCK_INPUT; + g_object_ref (x->handlebox_widget); + if (x->toolbar_in_hbox) + gtk_container_remove (GTK_CONTAINER (x->hbox_widget), + x->handlebox_widget); + else + gtk_container_remove (GTK_CONTAINER (x->vbox_widget), + x->handlebox_widget); + xg_pack_tool_bar (f, pos); + g_object_unref (x->handlebox_widget); + if (xg_update_tool_bar_sizes (f)) + xg_height_or_width_changed (f); + + UNBLOCK_INPUT; + return 1; +} + /*********************************************************************** diff -r 3021343b766a -r 06384b3caebf src/gtkutil.h --- a/src/gtkutil.h Thu Jul 29 12:01:14 2010 -0400 +++ b/src/gtkutil.h Thu Jul 29 18:49:59 2010 +0200 @@ -181,6 +181,7 @@ extern void update_frame_tool_bar (FRAME_PTR f); extern void free_frame_tool_bar (FRAME_PTR f); +extern int xg_change_toolbar_position (FRAME_PTR f, Lisp_Object pos); extern void xg_frame_resized (FRAME_PTR f, int pixelwidth, diff -r 3021343b766a -r 06384b3caebf src/window.c --- a/src/window.c Thu Jul 29 12:01:14 2010 -0400 +++ b/src/window.c Thu Jul 29 18:49:59 2010 +0200 @@ -645,13 +645,18 @@ #ifdef FRAME_MENUBAR_HEIGHT *add_y += FRAME_MENUBAR_HEIGHT (f); #endif -#ifdef FRAME_TOOLBAR_HEIGHT +#ifdef FRAME_TOOLBAR_TOP_HEIGHT + *add_y += FRAME_TOOLBAR_TOP_HEIGHT (f); +#elif FRAME_TOOLBAR_HEIGHT *add_y += FRAME_TOOLBAR_HEIGHT (f); #endif #ifdef FRAME_NS_TITLEBAR_HEIGHT *add_y += FRAME_NS_TITLEBAR_HEIGHT (f); #endif *add_x = f->left_pos; +#ifdef FRAME_TOOLBAR_LEFT_WIDTH + *add_x += FRAME_TOOLBAR_LEFT_WIDTH (f); +#endif } DEFUN ("window-absolute-pixel-edges", Fwindow_absolute_pixel_edges, diff -r 3021343b766a -r 06384b3caebf src/xfns.c --- a/src/xfns.c Thu Jul 29 12:01:14 2010 -0400 +++ b/src/xfns.c Thu Jul 29 18:49:59 2010 +0200 @@ -715,6 +715,23 @@ f->output_data.x->wait_for_wm = !NILP (new_value); } +static void +x_set_tool_bar_position (struct frame *f, + Lisp_Object new_value, + Lisp_Object old_value) +{ + if (! EQ (new_value, Qleft) && ! EQ (new_value, Qright) + && ! EQ (new_value, Qbottom) && ! EQ (new_value, Qtop)) + return; + if (EQ (new_value, old_value)) return; + +#ifdef USE_GTK + fprintf (stderr, "Pos: %s\n", SDATA (SYMBOL_NAME (new_value))); + if (xg_change_toolbar_position (f, new_value)) + f->tool_bar_position = new_value; +#endif +} + #ifdef USE_GTK /* Set icon from FILE for frame F. By using GTK functions the icon @@ -2344,7 +2361,7 @@ area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f); area.y = (FRAME_PIXEL_HEIGHT (f) - area.height - FRAME_MENUBAR_HEIGHT (f) - - FRAME_TOOLBAR_HEIGHT (f) + - FRAME_TOOLBAR_TOP_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f)); XFree (needed); @@ -5747,6 +5764,7 @@ x_set_font_backend, x_set_alpha, x_set_sticky, + x_set_tool_bar_position, }; void @@ -5897,6 +5915,7 @@ accepts --with-x-toolkit=gtk. */ Fprovide (intern_c_string ("x-toolkit"), Qnil); Fprovide (intern_c_string ("gtk"), Qnil); + Fprovide (intern_c_string ("move-toolbar"), Qnil); DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string, doc: /* Version info for GTK+. */); diff -r 3021343b766a -r 06384b3caebf src/xterm.c --- a/src/xterm.c Thu Jul 29 12:01:14 2010 -0400 +++ b/src/xterm.c Thu Jul 29 18:49:59 2010 +0200 @@ -8610,7 +8610,8 @@ compute_fringe_widths (f, 0); - pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols); + pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols) + + FRAME_TOOLBAR_WIDTH (f); pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); diff -r 3021343b766a -r 06384b3caebf src/xterm.h --- a/src/xterm.h Thu Jul 29 12:01:14 2010 -0400 +++ b/src/xterm.h Thu Jul 29 18:49:59 2010 +0200 @@ -433,9 +433,15 @@ if the menubar is turned off. */ int menubar_height; - /* Height of tool bar widget, in pixels. - Zero if not using an external tool bar. */ - int toolbar_height; + /* Height of tool bar widget, in pixels. top_height is used if tool bar + at top, bottom_height if tool bar is at the bottom. + Zero if not using an external tool bar or if tool bar is vertical. */ + int toolbar_top_height, toolbar_bottom_height; + + /* Width of tool bar widget, in pixels. left_width is used if tool bar + at left, right_width if tool bar is at the right. + Zero if not using an external tool bar or if tool bar is horizontal. */ + int toolbar_left_width, toolbar_right_width; /* The tiled border used when the mouse is out of the frame. */ Pixmap border_tile; @@ -480,6 +486,8 @@ GtkWidget *edit_widget; /* The widget used for laying out widgets vertically. */ GtkWidget *vbox_widget; + /* The widget used for laying out widgets horizontally. */ + GtkWidget *hbox_widget; /* The menubar in this frame. */ GtkWidget *menubar_widget; /* The tool bar in this frame */ @@ -488,6 +496,8 @@ GtkWidget *handlebox_widget; /* Non-zero if the tool bar is detached. */ int toolbar_detached; + /* Non-zero if tool bar is packed into the hbox widget (i.e. vertical). */ + int toolbar_in_hbox; /* The last size hints set. */ GdkGeometry size_hints; @@ -700,7 +710,15 @@ #define FRAME_FONT(f) ((f)->output_data.x->font) #define FRAME_FONTSET(f) ((f)->output_data.x->fontset) #define FRAME_MENUBAR_HEIGHT(f) ((f)->output_data.x->menubar_height) -#define FRAME_TOOLBAR_HEIGHT(f) ((f)->output_data.x->toolbar_height) +#define FRAME_TOOLBAR_TOP_HEIGHT(f) ((f)->output_data.x->toolbar_top_height) +#define FRAME_TOOLBAR_BOTTOM_HEIGHT(f) \ + ((f)->output_data.x->toolbar_bottom_height) +#define FRAME_TOOLBAR_HEIGHT(f) \ + (FRAME_TOOLBAR_TOP_HEIGHT (f) + FRAME_TOOLBAR_BOTTOM_HEIGHT (f)) +#define FRAME_TOOLBAR_LEFT_WIDTH(f) ((f)->output_data.x->toolbar_left_width) +#define FRAME_TOOLBAR_RIGHT_WIDTH(f) ((f)->output_data.x->toolbar_right_width) +#define FRAME_TOOLBAR_WIDTH(f) \ + (FRAME_TOOLBAR_LEFT_WIDTH (f) + FRAME_TOOLBAR_RIGHT_WIDTH (f)) #define FRAME_BASELINE_OFFSET(f) ((f)->output_data.x->baseline_offset) /* This gives the x_display_info structure for the display F is on. */