From 31e687a7c848bbc4e0a7ef34acc4f55a7d5a9004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vivek=20Das=C2=A0Mohapatra?= Date: Thu, 18 Oct 2018 01:38:05 +0100 Subject: [PATCH 3/3] Hook up menu bar scrollbar functionality to customize & Options menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit menu-bar-scrollbar-mode custom variable updates default and initial frame parameters. menu-bar-scrollbar-mode command cycles the custom variable through the available/supported values Options ► Show Hide ► Menu Bar Scroll/Truncate menu connected to the custom variable. --- lisp/menu-bar.el | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index e2ebd98119..0dc8757249 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -673,6 +673,7 @@ menu-bar-options-save line-number-mode column-number-mode size-indication-mode cua-mode show-paren-mode transient-mark-mode blink-cursor-mode display-time-mode display-battery-mode + menu-bar-scrollbar-mode ;; These are set by other functions that don't set ;; the customized state. Having them here has the ;; side-effect that turning them off via X @@ -1042,6 +1043,138 @@ menu-bar-showhide-tool-bar-menu-customize-enable-bottom (interactive) (menu-bar-set-tool-bar-position 'bottom)) +(defcustom menu-bar-scrollbar-mode nil + "Specify how GTK menu bars deal with the frame being too narrow to hold them.\n +Valid values are: + `always' - the menu bar always has a scrollbar + `automatic' - a scrollbar is added when required + `forced-resize' - no scrollbar, the frame is forced to resize to accommodate + the menu bar. + nil (or any other value) - the menu bar is truncated\n +Note that prior to GTK 3.16 truncation is not possible and the default +is equivalent to 'forced-resize.\n +Do not set this variable directly - use the customize interface to make sure +that `default-frame-alist', `initial-frame-alist' and all existing frames +remain in sync." + :version "26.2" + :type '(choice (const always) + (const automaic) + (const forced-resize) + (const nil)) + :group 'frames + :initialize 'custom-initialize-default + :set (lambda (sym val) + (setq val (if (memq val '(automatic always forced-resize)) val nil)) + (set-default sym val) + (modify-all-frames-parameters + (list (cons 'menu-bar-scrollbar val))))) + +(defun menu-bar-can-be-truncated () + (let (version) + (when (boundp 'gtk-version-string) + (setq version (mapcar 'string-to-number (split-string gtk-version-string "\\."))) + (or (and (eq (car version) 3) (>= (cadr version) 16)) + (>= (car version) 4))))) + +(defun menu-bar-scrollbar-next-mode (mode) + "Return the next menu-bar-scrollbar frame parameter value after MODE. +Takes into account the abilities of the available GTK version." + (if (menu-bar-can-be-truncated) + (progn + (if (not (memq mode '(always automatic forced-resize nil))) (setq mode nil)) + (cadr (memq mode '(nil automatic always forced-resize nil)))) + (if (not (memq mode '(always automatic nil))) (setq mode nil)) + (cadr (memq mode '(nil automatic always nil))))) + +(defun menu-bar-scrollbar-mode (&optional mode) + "Cycle through scroll/truncate/resize modes for GTK menu bars.\n +If the optional parameter MODE is specified then apply that instead. +The new mode is stored in the variable `menu-bar-scrollbar-mode' via +the custom interface (but not automatically saved).\n +Returns the new MODE.\n +NOTE: pass 'default if you want to set the mode explicitly to nil.\n +See `menu-bar-scrollbar' in Info node `(elisp)Layout Parameters' for details." + (interactive) + (if mode + ;; explicit mode passed, map any non-standard value back to nil + (setq mode (car (memq mode '(automatic always forced-resize)))) + ;; no explicit mode: pick the new value based on our fixed progression: + (setq mode (menu-bar-scrollbar-next-mode + (or menu-bar-scrollbar-mode 'default)))) + ;; set, apply but do not save the new value: + (customize-set-variable 'menu-bar-scrollbar-mode mode) + mode) + +(defun menu-bar-showhide-menu-bar-scrollbar-mode-customize-forced-resize () + "Resize the frame to accommodate the menu bar." + (interactive) + (customize-set-variable 'menu-bar-scrollbar-mode 'forced-resize)) +(defun menu-bar-showhide-menu-bar-scrollbar-mode-customize-always () + "Add a permanent scrollbar to the menu bar." + (interactive) + (customize-set-variable 'menu-bar-scrollbar-mode 'always)) +(defun menu-bar-showhide-menu-bar-scrollbar-mode-customize-automatic () + "Add a scrollbar to the menu bar when it tries to grow past the frame edge.." + (interactive) + (customize-set-variable 'menu-bar-scrollbar-mode 'automatic)) +(defun menu-bar-showhide-menu-bar-scrollbar-mode-customize-nil () + "Truncate the menu bar to fit the frame." + (interactive) + (customize-set-variable 'menu-bar-scrollbar-mode 'default)) + +(when (featurep 'gtk) + (defvar menu-bar-showhide-menu-bar-scrollbar-mode-menu + (let ((menu (make-sparse-keymap "Menu Bar Scroll/Truncate"))) + + (bindings--define-key menu [showhide-menu-bar-scrollbar-mode-forced-resize] + '(menu-item "Resize Frame" + menu-bar-showhide-menu-bar-scrollbar-mode-customize-forced-resize + :help "Resize the frame to accommodate the menu bar" + :visible (display-graphic-p) + :button + (:radio . (if (menu-bar-can-be-truncated) + (eq (frame-parameter + (menu-bar-frame-for-menubar) + 'menu-bar-scrollbar) + 'forced-resize) + (not (memq (frame-parameter + (menu-bar-frame-for-menubar) + 'menu-bar-scrollbar) + '(automatic always))))))) + + (bindings--define-key menu [showhide-menu-bar-scrollbar-mode-always] + '(menu-item "Always Scroll" + menu-bar-showhide-menu-bar-scrollbar-mode-customize-always + :help "Always add a scroll bar to the menu bar" + :visible (display-graphic-p) + :button + (:radio . (eq (frame-parameter (menu-bar-frame-for-menubar) + 'menu-bar-scrollbar) + 'always)))) + + (bindings--define-key menu [showhide-menu-bar-scrollbar-mode-automatic] + '(menu-item "Automatic" + menu-bar-showhide-menu-bar-scrollbar-mode-customize-automatic + :help "Display a scroll bar only when the menu is too wide" + :visible (display-graphic-p) + :button + (:radio . (eq (frame-parameter (menu-bar-frame-for-menubar) + 'menu-bar-scrollbar) + 'automatic)))) + + (bindings--define-key menu [showhide-menu-bar-scrollbar-mode-truncate] + '(menu-item "Truncate" + menu-bar-showhide-menu-bar-scrollbar-mode-customize-nil + :help "Truncate the menubar to fit inside the frame" + :visible (and (display-graphic-p) + (menu-bar-can-be-truncated)) + :button + (:radio . (not (memq + (frame-parameter (menu-bar-frame-for-menubar) + 'menu-bar-scrollbar) + '(automatic always forced-resize)))))) + menu))) + (when (featurep 'move-toolbar) (defvar menu-bar-showhide-tool-bar-menu (let ((menu (make-sparse-keymap "Tool Bar"))) @@ -1225,6 +1358,12 @@ menu-bar-showhide-menu :visible (and (display-graphic-p) (fboundp 'x-show-tip)) :button (:toggle . tooltip-mode))) + (when (featurep 'gtk) + (bindings--define-key menu [showhide-menu-bar-scrollbar-menu] + `(menu-item "Menu Bar Scroll/Truncate" + ,menu-bar-showhide-menu-bar-scrollbar-mode-menu + :visible (display-graphic-p)))) + (bindings--define-key menu [menu-bar-mode] '(menu-item "Menu Bar" toggle-menu-bar-mode-from-frame :help "Turn menu bar on/off" -- 2.11.0