diff options
| author | Jan D | 2010-05-16 20:49:26 +0200 |
|---|---|---|
| committer | Jan D | 2010-05-16 20:49:26 +0200 |
| commit | df68b7080ffc59c18f3289a3d4eb157f7c111454 (patch) | |
| tree | 49e8c75ac59e77613bd18826319d2f65b8bd2ce0 | |
| parent | a2b9f1182d6159061079fa0b480ec9ff81cc95f1 (diff) | |
| download | emacs-gtk-tabs.tar.gz emacs-gtk-tabs.zip | |
Tab keys are symbols.gtk-tabs
Tab switch is in elisp.
Save/restore point in tabs also.
| -rw-r--r-- | lisp/native-tabs.el | 134 | ||||
| -rw-r--r-- | src/emacs.c | 3 | ||||
| -rw-r--r-- | src/gtkutil.c | 384 | ||||
| -rw-r--r-- | src/gtkutil.h | 3 | ||||
| -rw-r--r-- | src/lisp.h | 3 | ||||
| -rw-r--r-- | src/window.c | 2 | ||||
| -rw-r--r-- | src/xfns.c | 26 | ||||
| -rw-r--r-- | src/xterm.c | 8 | ||||
| -rw-r--r-- | src/xterm.h | 2 |
9 files changed, 252 insertions, 313 deletions
diff --git a/lisp/native-tabs.el b/lisp/native-tabs.el index afd46a9124b..283c7a640dd 100644 --- a/lisp/native-tabs.el +++ b/lisp/native-tabs.el | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | (define-key map "\C-x70" 'tab-delete) | 33 | (define-key map "\C-x70" 'tab-delete) |
| 34 | (define-key map "\C-x71" 'tab-delete-other) | 34 | (define-key map "\C-x71" 'tab-delete-other) |
| 35 | (define-key map "\C-x72" 'tab-new) | 35 | (define-key map "\C-x72" 'tab-new) |
| 36 | (define-key map "\C-x73" 'switch-to-buffer-tab) | 36 | (define-key map "\C-x73" 'switch-to-buffer-in-tab) |
| 37 | (define-key map "\C-x7b" 'switch-to-buffer-other-tab) | 37 | (define-key map "\C-x7b" 'switch-to-buffer-other-tab) |
| 38 | (define-key map "\C-x7f" 'find-file-new-tab) | 38 | (define-key map "\C-x7f" 'find-file-new-tab) |
| 39 | (define-key map "\C-x7o" 'tab-next) | 39 | (define-key map "\C-x7o" 'tab-next) |
| @@ -58,16 +58,34 @@ Keyboard commands for tabs are: | |||
| 58 | :keymap tab-mode-map | 58 | :keymap tab-mode-map |
| 59 | (modify-all-frames-parameters (list (cons 'disable-tabs (not tab-mode))))) | 59 | (modify-all-frames-parameters (list (cons 'disable-tabs (not tab-mode))))) |
| 60 | 60 | ||
| 61 | (declare-function tab-new "xfns.c" ()) | 61 | (declare-function tab-new "xfns.c" (&optional label frame)) |
| 62 | (declare-function tab-delete "xfns.c" ()) | 62 | (declare-function tab-delete "xfns.c" (&optional label frame)) |
| 63 | (declare-function tab-delete-other "xfns.c" ()) | 63 | (declare-function tab-delete-other "xfns.c" (&optional frame)) |
| 64 | (declare-function tab-next "xfns.c" ()) | 64 | (declare-function tab-next "xfns.c" (&optional frame)) |
| 65 | (declare-function tab-previous "xfns.c" ()) | 65 | (declare-function tab-previous "xfns.c" (&optional frame)) |
| 66 | (declare-function tab-nr-of-tabs "xfns.c" ()) | 66 | (declare-function tab-nr-of-tabs "xfns.c" (&optional frame)) |
| 67 | (declare-function tab-configuration "xfns.c" ()) | 67 | (declare-function tab-current "xfns.c" (&optional frame)) |
| 68 | (declare-function tab-current "xfns.c" ()) | 68 | (declare-function tab-show "xfns.c" (key &optional frame)) |
| 69 | (declare-function tab-show "xfns.c" ()) | 69 | (declare-function tab-enable "xfns.c" (enable &optional frame)) |
| 70 | (declare-function tab-enable "xfns.c" ()) | 70 | |
| 71 | (defun current-tab-window-config () | ||
| 72 | (list (current-window-configuration) (point-marker))) | ||
| 73 | |||
| 74 | (defun window-tab-config-frame (config) | ||
| 75 | (if (and (consp config) (window-configuration-p (car config))) | ||
| 76 | (window-configuration-frame (car config)) | ||
| 77 | nil)) | ||
| 78 | |||
| 79 | (defun set-tab-window-config (config) | ||
| 80 | (and (consp config) (window-configuration-p (car config)) | ||
| 81 | (set-window-configuration (car config)) | ||
| 82 | (goto-char (cadr config)))) | ||
| 83 | |||
| 84 | (defun change-tab-window-config-frame (config frame) | ||
| 85 | (if (and (consp config) (window-configuration-p (car config))) | ||
| 86 | (list (change-window-configuration-frame (car config) frame) | ||
| 87 | (cadr config)) | ||
| 88 | config)) | ||
| 71 | 89 | ||
| 72 | (defun find-file-new-tab (filename &optional wildcards) | 90 | (defun find-file-new-tab (filename &optional wildcards) |
| 73 | "Edit file FILENAME, in a new tab. | 91 | "Edit file FILENAME, in a new tab. |
| @@ -83,16 +101,20 @@ expand wildcards (if any) and visit multiple files." | |||
| 83 | (interactive | 101 | (interactive |
| 84 | (find-file-read-args "Find file in new tab: " | 102 | (find-file-read-args "Find file in new tab: " |
| 85 | (confirm-nonexistent-file-or-buffer))) | 103 | (confirm-nonexistent-file-or-buffer))) |
| 86 | (let ((value (find-file-noselect filename nil nil wildcards))) | 104 | (save-window-excursion |
| 87 | (if (not (null (tab-new))) | 105 | (let* ((value (find-file-noselect filename nil nil wildcards)) |
| 88 | (progn | 106 | (newtab (tab-new))) |
| 89 | (delete-other-windows) | 107 | (if newtab |
| 90 | (if (listp value) | 108 | (progn |
| 91 | (progn | 109 | (delete-other-windows) |
| 92 | (setq value (nreverse value)) | 110 | (if (listp value) |
| 93 | (cons (switch-to-buffer (car value)) | 111 | (progn |
| 94 | (mapcar 'switch-to-buffer (cdr value)))) | 112 | (setq value (nreverse value)) |
| 95 | (switch-to-buffer value)))))) | 113 | (cons (switch-to-buffer (car value)) |
| 114 | (dolist 'switch-to-buffer (cdr value)))) | ||
| 115 | (switch-to-buffer value)) | ||
| 116 | (put newtab 'winconfig (current-tab-window-config))))))) | ||
| 117 | |||
| 96 | 118 | ||
| 97 | (defun switch-to-buffer-other-tab (buffer-or-name &optional norecord) | 119 | (defun switch-to-buffer-other-tab (buffer-or-name &optional norecord) |
| 98 | "Switch to buffer BUFFER-OR-NAME in another tab. | 120 | "Switch to buffer BUFFER-OR-NAME in another tab. |
| @@ -123,8 +145,8 @@ documentation for additional customization information." | |||
| 123 | (delete-other-windows))))) | 145 | (delete-other-windows))))) |
| 124 | 146 | ||
| 125 | 147 | ||
| 126 | (defun display-existing-buffer-in-tab (buffer-or-name &optional frame) | 148 | (defun find-tab-for-existing-buffer (buffer-or-name &optional frame) |
| 127 | "Switch to a tab that shows BUFFER-OR-NAME on FRAME. | 149 | "Find a tab that shows BUFFER-OR-NAME on FRAME. |
| 128 | FRAME nil means selected frame. | 150 | FRAME nil means selected frame. |
| 129 | 151 | ||
| 130 | Returns the key for the tab switch to, or nil if no tab displays | 152 | Returns the key for the tab switch to, or nil if no tab displays |
| @@ -136,21 +158,19 @@ BUFFER-OR-NAME." | |||
| 136 | (tab-key)) | 158 | (tab-key)) |
| 137 | (while (and tabs (null tab-key)) | 159 | (while (and tabs (null tab-key)) |
| 138 | (let* ((elt (car tabs)) | 160 | (let* ((elt (car tabs)) |
| 139 | (winconf (cadr elt)) | 161 | (winconf (get elt 'winconfig)) |
| 140 | (buffers (buffers-in-window-configuration winconf))) | 162 | (buffers (buffers-in-window-configuration winconf))) |
| 141 | (if (memq buffer buffers) | 163 | (if (memq buffer buffers) |
| 142 | (setq tab-key (car elt)) | 164 | (setq tab-key elt) |
| 143 | (setq tabs (cdr tabs))))) | 165 | (setq tabs (cdr tabs))))) |
| 144 | (if (and tab-key (not (equal tab-key (tab-current frame)))) | 166 | tab-key)) |
| 145 | (progn | ||
| 146 | (tab-show tab-key frame) | ||
| 147 | tab-key) | ||
| 148 | nil))) | ||
| 149 | 167 | ||
| 150 | (defun switch-to-buffer-tab (buffer-or-name &optional frame) | 168 | (defun switch-to-buffer-in-tab (buffer-or-name &optional frame) |
| 151 | (interactive "BSwitch to buffer:\nP") | 169 | (interactive "BSwitch to buffer:\nP") |
| 152 | (if (not (display-existing-buffer-in-tab buffer-or-name frame)) | 170 | (let ((tab (find-tab-for-existing-buffer buffer-or-name frame))) |
| 153 | (switch-to-buffer buffer-or-name))) | 171 | (if tab |
| 172 | (tab-show tab frame) | ||
| 173 | (switch-to-buffer buffer-or-name)))) | ||
| 154 | 174 | ||
| 155 | (defun handle-tab-event (event) | 175 | (defun handle-tab-event (event) |
| 156 | "Handle tab-event to change tabs on the frame in EVENT." | 176 | "Handle tab-event to change tabs on the frame in EVENT." |
| @@ -161,23 +181,35 @@ BUFFER-OR-NAME." | |||
| 161 | (frame (car n1)) | 181 | (frame (car n1)) |
| 162 | (x (car (cdr n1))) | 182 | (x (car (cdr n1))) |
| 163 | (y (cdr (cdr n1)))) | 183 | (y (cdr (cdr n1)))) |
| 164 | (if (eq type 2) ;; // A tab is dropped from another frame. | ||
| 165 | (let ((top y) | ||
| 166 | (left x) | ||
| 167 | (width (frame-pixel-width frame)) | ||
| 168 | (height (frame-pixel-height frame)) | ||
| 169 | (dw (x-display-pixel-width frame)) | ||
| 170 | (dh (x-display-pixel-height frame))) | ||
| 171 | (if (< dw (+ left width)) | ||
| 172 | (setq left (- dw width))) | ||
| 173 | (if (< dh (+ top height)) | ||
| 174 | (setq top (- dh height))) | ||
| 175 | (make-frame | ||
| 176 | (list (cons 'width (frame-parameter frame 'width)) | ||
| 177 | (cons 'height(frame-parameter frame 'height)) | ||
| 178 | (cons 'top top) | ||
| 179 | (cons 'left left))))))) | ||
| 180 | |||
| 181 | (define-key special-event-map [tab-event] 'handle-tab-event) | ||
| 182 | 184 | ||
| 185 | (cond ((eq type 'tab-new-frame) ;; // A tab is dropped to the background. | ||
| 186 | (let ((tab (car (cdr n2))) | ||
| 187 | (top y) | ||
| 188 | (left x) | ||
| 189 | (width (frame-pixel-width frame)) | ||
| 190 | (height (frame-pixel-height frame)) | ||
| 191 | (dw (x-display-pixel-width frame)) | ||
| 192 | (dh (x-display-pixel-height frame))) | ||
| 193 | (if (< dw (+ left width)) | ||
| 194 | (setq left (- dw width))) | ||
| 195 | (if (< dh (+ top height)) | ||
| 196 | (setq top (- dh height))) | ||
| 197 | (make-frame | ||
| 198 | (list (cons 'width (frame-parameter frame 'width)) | ||
| 199 | (cons 'height(frame-parameter frame 'height)) | ||
| 200 | (cons 'top top) | ||
| 201 | (cons 'left left))))) | ||
| 202 | |||
| 203 | ((eq type 'tab-changed) | ||
| 204 | (let* ((newtab (car (cdr n2))) | ||
| 205 | (newcfg (get newtab 'winconfig)) | ||
| 206 | (oldtab (cdr (cdr n2)))) | ||
| 207 | (if oldtab (put oldtab 'winconfig (current-tab-window-config))) | ||
| 208 | (if newcfg (set-tab-window-config | ||
| 209 | (if (eq (window-tab-config-frame newcfg) frame) | ||
| 210 | newcfg | ||
| 211 | (put newtab 'winconfig | ||
| 212 | (change-tab-window-config-frame newcfg frame)))) | ||
| 213 | (delete-other-windows))))))) | ||
| 183 | 214 | ||
| 215 | (define-key special-event-map [tab-event] 'handle-tab-event) | ||
diff --git a/src/emacs.c b/src/emacs.c index 400a6b0e594..72680e37615 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -1626,6 +1626,9 @@ main (int argc, char **argv) | |||
| 1626 | syms_of_xmenu (); | 1626 | syms_of_xmenu (); |
| 1627 | syms_of_fontset (); | 1627 | syms_of_fontset (); |
| 1628 | syms_of_xsettings (); | 1628 | syms_of_xsettings (); |
| 1629 | #ifdef USE_GTK | ||
| 1630 | syms_of_gtkutil (); | ||
| 1631 | #endif | ||
| 1629 | #ifdef HAVE_X_SM | 1632 | #ifdef HAVE_X_SM |
| 1630 | syms_of_xsmfns (); | 1633 | syms_of_xsmfns (); |
| 1631 | #endif | 1634 | #endif |
diff --git a/src/gtkutil.c b/src/gtkutil.c index 491b1a1c014..fbe744b5124 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -46,6 +46,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 46 | /* Avoid "differ in sign" warnings */ | 46 | /* Avoid "differ in sign" warnings */ |
| 47 | #define SSDATA(x) ((char *) SDATA (x)) | 47 | #define SSDATA(x) ((char *) SDATA (x)) |
| 48 | 48 | ||
| 49 | static Lisp_Object Qfile_sans_ext, Qx_gtk_map_stock; | ||
| 50 | |||
| 49 | 51 | ||
| 50 | /*********************************************************************** | 52 | /*********************************************************************** |
| 51 | Display handling functions | 53 | Display handling functions |
| @@ -758,34 +760,31 @@ xg_pix_to_gcolor (w, pixel, c) | |||
| 758 | Tab functions | 760 | Tab functions |
| 759 | ***********************************************************************/ | 761 | ***********************************************************************/ |
| 760 | #define XG_TAB_KEY "emacs-tab-key" | 762 | #define XG_TAB_KEY "emacs-tab-key" |
| 761 | #define XG_TAB_CONFIG_KEY "emacs-tab-config-key" | 763 | |
| 762 | static int xg_tab_nr; | 764 | static int xg_tab_nr; |
| 763 | static xg_list_node tabs_gc_list; | ||
| 764 | static GtkNotebook* notebook_on_hold; | 765 | static GtkNotebook* notebook_on_hold; |
| 766 | static Lisp_Object Qtab_new_frame, Qtab_changed, Qtab_added, Qtab_removed; | ||
| 765 | 767 | ||
| 766 | /* If 1, show tabs even if there is only one tab. */ | 768 | /* If non-zero, show tabs even if there is only one tab. */ |
| 767 | static int xg_always_show_tabs; | 769 | static int xg_always_show_tabs; |
| 768 | 770 | ||
| 769 | typedef struct | 771 | static void |
| 770 | { | 772 | store_tab_event (FRAME_PTR f, |
| 771 | xg_list_node ptrs; | 773 | Lisp_Object arg, |
| 772 | Lisp_Object object; | 774 | int x, |
| 773 | } tabs_gc_data; | 775 | int y) |
| 774 | |||
| 775 | |||
| 776 | /* Store the current window configuration for frame F in widget W. */ | ||
| 777 | |||
| 778 | static tabs_gc_data * | ||
| 779 | xg_store_win_config (GtkWidget *w, FRAME_PTR f) | ||
| 780 | { | 776 | { |
| 777 | struct input_event event; | ||
| 781 | Lisp_Object frame; | 778 | Lisp_Object frame; |
| 782 | tabs_gc_data *conf = xmalloc (sizeof(*conf)); | ||
| 783 | XSETFRAME (frame, f); | 779 | XSETFRAME (frame, f); |
| 784 | g_object_set_data (G_OBJECT (w), XG_TAB_CONFIG_KEY, conf); | ||
| 785 | xg_list_insert (&tabs_gc_list, &conf->ptrs); | ||
| 786 | conf->object = Fcurrent_window_configuration (frame); | ||
| 787 | 780 | ||
| 788 | return conf; | 781 | EVENT_INIT (event); |
| 782 | event.kind = TAB_EVENT; | ||
| 783 | event.frame_or_window = frame; | ||
| 784 | event.arg = arg; | ||
| 785 | event.x = make_number (x); | ||
| 786 | event.y = make_number (y); | ||
| 787 | kbd_buffer_store_event (&event); | ||
| 789 | } | 788 | } |
| 790 | 789 | ||
| 791 | static void | 790 | static void |
| @@ -798,17 +797,24 @@ xg_check_show_tabs (FRAME_PTR f, | |||
| 798 | 797 | ||
| 799 | if ((shown && !should_show) || (!shown && should_show)) | 798 | if ((shown && !should_show) || (!shown && should_show)) |
| 800 | { | 799 | { |
| 801 | GtkRequisition req; | ||
| 802 | int oldheight, row_add = 0; | 800 | int oldheight, row_add = 0; |
| 803 | 801 | ||
| 802 | if (should_show) | ||
| 803 | gtk_widget_show_all (GTK_WIDGET (wnote)); | ||
| 804 | else | ||
| 805 | gtk_widget_hide (GTK_WIDGET (wnote)); | ||
| 804 | gtk_notebook_set_show_tabs (wnote, should_show); | 806 | gtk_notebook_set_show_tabs (wnote, should_show); |
| 805 | oldheight = FRAME_TABS_HEIGHT (f); | 807 | oldheight = FRAME_TABS_HEIGHT (f); |
| 806 | 808 | ||
| 807 | gtk_widget_size_request (f->output_data.x->notebook_widget, &req); | 809 | if (should_show) |
| 808 | if (req.height > FRAME_PIXEL_HEIGHT (f)) | 810 | { |
| 809 | FRAME_TABS_HEIGHT (f) = req.height - FRAME_PIXEL_HEIGHT (f); | 811 | GtkRequisition req; |
| 812 | gtk_widget_size_request (f->output_data.x->notebook_widget, &req); | ||
| 813 | FRAME_TABS_HEIGHT (f) = req.height; | ||
| 814 | } | ||
| 810 | else | 815 | else |
| 811 | FRAME_TABS_HEIGHT (f) = 0; | 816 | FRAME_TABS_HEIGHT (f) = 0; |
| 817 | |||
| 812 | x_wm_set_size_hint (f, 0, 0); | 818 | x_wm_set_size_hint (f, 0, 0); |
| 813 | 819 | ||
| 814 | /* Try to minimize resize, when adding/removing the tabs, add some text | 820 | /* Try to minimize resize, when adding/removing the tabs, add some text |
| @@ -829,8 +835,7 @@ xg_check_show_tabs (FRAME_PTR f, | |||
| 829 | } | 835 | } |
| 830 | } | 836 | } |
| 831 | 837 | ||
| 832 | /* Callback called when a new tab has been added. | 838 | /* Callback called when a new tab has been added. */ |
| 833 | Handle the case when a page has been dropped from another frame. */ | ||
| 834 | 839 | ||
| 835 | static void | 840 | static void |
| 836 | xg_page_added_cb (GtkNotebook *notebook, | 841 | xg_page_added_cb (GtkNotebook *notebook, |
| @@ -839,19 +844,37 @@ xg_page_added_cb (GtkNotebook *notebook, | |||
| 839 | gpointer user_data) | 844 | gpointer user_data) |
| 840 | { | 845 | { |
| 841 | FRAME_PTR f = (FRAME_PTR) user_data; | 846 | FRAME_PTR f = (FRAME_PTR) user_data; |
| 842 | tabs_gc_data *conf = g_object_get_data (G_OBJECT (child), XG_TAB_CONFIG_KEY); | 847 | char *newkey = g_object_get_data (G_OBJECT (child), XG_TAB_KEY); |
| 848 | GtkWidget *old = f->output_data.x->current_tab; | ||
| 843 | 849 | ||
| 844 | /* Dropped from another frame? */ | 850 | store_tab_event (f, Fcons (Qtab_added, |
| 845 | if (conf | 851 | Fcons (intern (newkey), Qnil)), |
| 846 | && Fwindow_configuration_p (conf->object) && | 852 | 0, 0); |
| 847 | XFRAME (Fwindow_configuration_frame (conf->object)) != f) | 853 | if (old == NULL) |
| 848 | { | 854 | { |
| 849 | Lisp_Object frame; | 855 | old = child; |
| 850 | XSETFRAME (frame, f); | 856 | store_tab_event (f, Fcons (Qtab_changed, Fcons (intern (newkey), Qnil)), |
| 851 | Fchange_window_configuration_frame (conf->object, frame); | 857 | 0, 0); |
| 852 | } | 858 | } |
| 853 | } | 859 | } |
| 854 | 860 | ||
| 861 | /* Callback called when a new tab has been added. */ | ||
| 862 | |||
| 863 | static void | ||
| 864 | xg_page_removed_cb (GtkNotebook *notebook, | ||
| 865 | GtkWidget *child, | ||
| 866 | guint page_num, | ||
| 867 | gpointer user_data) | ||
| 868 | { | ||
| 869 | FRAME_PTR f = (FRAME_PTR) user_data; | ||
| 870 | char *key = g_object_get_data (G_OBJECT (child), XG_TAB_KEY); | ||
| 871 | |||
| 872 | store_tab_event (f, Fcons (Qtab_removed, | ||
| 873 | Fcons (intern (key), Qnil)), | ||
| 874 | 0, 0); | ||
| 875 | |||
| 876 | } | ||
| 877 | |||
| 855 | /* Callback called when the current tab changes. */ | 878 | /* Callback called when the current tab changes. */ |
| 856 | 879 | ||
| 857 | static void | 880 | static void |
| @@ -860,75 +883,26 @@ xg_switch_page_cb (GtkNotebook *wnote, | |||
| 860 | guint page_num, | 883 | guint page_num, |
| 861 | gpointer user_data) | 884 | gpointer user_data) |
| 862 | { | 885 | { |
| 863 | BLOCK_INPUT; | ||
| 864 | GtkWidget *w = gtk_notebook_get_nth_page (wnote, page_num); | 886 | GtkWidget *w = gtk_notebook_get_nth_page (wnote, page_num); |
| 865 | FRAME_PTR f = (FRAME_PTR) user_data; | 887 | FRAME_PTR f = (FRAME_PTR) user_data; |
| 888 | GtkWidget *old = f->output_data.x->current_tab; | ||
| 866 | 889 | ||
| 867 | if (FRAME_GTK_WIDGET (f) && w != FRAME_GTK_WIDGET (f)) | 890 | BLOCK_INPUT; |
| 891 | if (w != old) | ||
| 868 | { | 892 | { |
| 869 | GtkWidget *old = FRAME_GTK_WIDGET (f); | ||
| 870 | GList *children = old ? GTK_FIXED (old)->children : NULL; | ||
| 871 | GSList *todo = NULL, *iter; | ||
| 872 | char *key = g_object_get_data (G_OBJECT (w), XG_TAB_KEY); | 893 | char *key = g_object_get_data (G_OBJECT (w), XG_TAB_KEY); |
| 873 | tabs_gc_data *conf = g_object_get_data (G_OBJECT (w), XG_TAB_CONFIG_KEY); | 894 | char *oldkey = old |
| 874 | 895 | ? g_object_get_data (G_OBJECT (old), XG_TAB_KEY) | |
| 875 | if (!w->window) gtk_widget_realize (w); | 896 | : NULL; |
| 876 | FRAME_GTK_WIDGET (f) = w; | 897 | |
| 877 | FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (w); | 898 | store_tab_event (f, |
| 878 | for ( ; children; children = g_list_next (children)) | 899 | Fcons (Qtab_changed, |
| 879 | { | 900 | Fcons (intern (key), |
| 880 | GtkFixedChild *child = (GtkFixedChild*)children->data; | 901 | oldkey ? intern (oldkey) : Qnil)), |
| 881 | if (GTK_IS_EVENT_BOX (child->widget)) | 902 | 0, 0); |
| 882 | { | ||
| 883 | GtkFixedChild *node = xmalloc (sizeof(*node)); | ||
| 884 | *node = *child; | ||
| 885 | todo = g_slist_prepend (todo, node); | ||
| 886 | } | ||
| 887 | } | ||
| 888 | |||
| 889 | for (iter = todo; iter; iter = g_slist_next (iter)) | ||
| 890 | { | ||
| 891 | GtkFixedChild *child = (GtkFixedChild*)iter->data; | ||
| 892 | GtkWidget *wevbox = child->widget; | ||
| 893 | g_object_ref (G_OBJECT (wevbox)); | ||
| 894 | gtk_container_remove (GTK_CONTAINER (old), wevbox); | ||
| 895 | gtk_fixed_put (GTK_FIXED (w), wevbox, child->x, child->y); | ||
| 896 | g_object_unref (G_OBJECT (wevbox)); | ||
| 897 | xfree (child); | ||
| 898 | iter->data = NULL; | ||
| 899 | } | ||
| 900 | if (todo) g_slist_free (todo); | ||
| 901 | |||
| 902 | SET_FRAME_GARBAGED (f); | ||
| 903 | cancel_mouse_face (f); | ||
| 904 | |||
| 905 | if (old) | ||
| 906 | { | ||
| 907 | struct input_event event; | ||
| 908 | Lisp_Object frame; | ||
| 909 | |||
| 910 | char *oldkey = g_object_get_data (G_OBJECT (old), XG_TAB_KEY); | ||
| 911 | tabs_gc_data *oconf = g_object_get_data (G_OBJECT (old), | ||
| 912 | XG_TAB_CONFIG_KEY); | ||
| 913 | if (!oconf) | ||
| 914 | oconf = xg_store_win_config (old, f); | ||
| 915 | |||
| 916 | XSETFRAME (frame, f); | ||
| 917 | |||
| 918 | EVENT_INIT (event); | ||
| 919 | event.kind = TAB_EVENT; | ||
| 920 | event.frame_or_window = frame; | ||
| 921 | event.arg = Fcons (make_number (1), | ||
| 922 | Fcons (make_string (key, strlen (key)), | ||
| 923 | make_string (oldkey, strlen (oldkey)))); | ||
| 924 | kbd_buffer_store_event (&event); | ||
| 925 | } | ||
| 926 | |||
| 927 | if (conf) | ||
| 928 | Fset_window_configuration (conf->object); | ||
| 929 | else | ||
| 930 | Fdelete_other_windows (Qnil); | ||
| 931 | } | 903 | } |
| 904 | |||
| 905 | f->output_data.x->current_tab = w; | ||
| 932 | xg_check_show_tabs (f, wnote); | 906 | xg_check_show_tabs (f, wnote); |
| 933 | UNBLOCK_INPUT; | 907 | UNBLOCK_INPUT; |
| 934 | } | 908 | } |
| @@ -938,12 +912,6 @@ xg_fixed_destroy_cb (GtkWidget *widget, | |||
| 938 | gpointer client_data) | 912 | gpointer client_data) |
| 939 | { | 913 | { |
| 940 | char *key = g_object_get_data (G_OBJECT (widget), XG_TAB_KEY); | 914 | char *key = g_object_get_data (G_OBJECT (widget), XG_TAB_KEY); |
| 941 | tabs_gc_data *conf = g_object_get_data (G_OBJECT (widget), XG_TAB_CONFIG_KEY); | ||
| 942 | if (conf) | ||
| 943 | { | ||
| 944 | xg_list_remove (&tabs_gc_list, &conf->ptrs); | ||
| 945 | xfree (conf); | ||
| 946 | } | ||
| 947 | xfree (key); | 915 | xfree (key); |
| 948 | } | 916 | } |
| 949 | 917 | ||
| @@ -1006,8 +974,6 @@ xg_add_fixed (FRAME_PTR f) | |||
| 1006 | GtkWidget *wfixed = gtk_fixed_new (); | 974 | GtkWidget *wfixed = gtk_fixed_new (); |
| 1007 | GdkColor bg; | 975 | GdkColor bg; |
| 1008 | GtkRcStyle *style; | 976 | GtkRcStyle *style; |
| 1009 | char buf[64]; | ||
| 1010 | char *key; | ||
| 1011 | 977 | ||
| 1012 | gtk_widget_set_name (wfixed, SSDATA (Vx_resource_name)); | 978 | gtk_widget_set_name (wfixed, SSDATA (Vx_resource_name)); |
| 1013 | g_object_set_data (G_OBJECT (wfixed), XG_FRAME_DATA, (gpointer)f); | 979 | g_object_set_data (G_OBJECT (wfixed), XG_FRAME_DATA, (gpointer)f); |
| @@ -1046,16 +1012,25 @@ xg_add_fixed (FRAME_PTR f) | |||
| 1046 | gtk_widget_modify_style (wfixed, style); | 1012 | gtk_widget_modify_style (wfixed, style); |
| 1047 | gtk_widget_show (wfixed); | 1013 | gtk_widget_show (wfixed); |
| 1048 | 1014 | ||
| 1049 | /* Not really needed on tab-less frames, but set it anyway so enabling | 1015 | return wfixed; |
| 1050 | of tabs later becomes easier. */ | 1016 | } |
| 1051 | sprintf (buf, "Page %d", xg_tab_nr++); | 1017 | |
| 1018 | static GtkWidget * | ||
| 1019 | xg_add_fixed_for_tab (FRAME_PTR f) | ||
| 1020 | { | ||
| 1021 | char buf[64]; | ||
| 1022 | GtkWidget *wfixed = gtk_fixed_new (); | ||
| 1023 | char *key; | ||
| 1024 | |||
| 1025 | gtk_widget_set_size_request (wfixed, 0, 0); | ||
| 1026 | g_object_set_data (G_OBJECT (wfixed), XG_FRAME_DATA, (gpointer)f); | ||
| 1027 | sprintf (buf, "Page_%d", xg_tab_nr++); | ||
| 1052 | key = xstrdup (buf); | 1028 | key = xstrdup (buf); |
| 1053 | g_object_set_data (G_OBJECT (wfixed), XG_TAB_KEY, key); | 1029 | g_object_set_data (G_OBJECT (wfixed), XG_TAB_KEY, key); |
| 1054 | g_signal_connect (G_OBJECT (wfixed), | 1030 | g_signal_connect (G_OBJECT (wfixed), |
| 1055 | "destroy", | 1031 | "destroy", |
| 1056 | G_CALLBACK (xg_fixed_destroy_cb), 0); | 1032 | G_CALLBACK (xg_fixed_destroy_cb), 0); |
| 1057 | 1033 | gtk_widget_show (wfixed); | |
| 1058 | |||
| 1059 | return wfixed; | 1034 | return wfixed; |
| 1060 | } | 1035 | } |
| 1061 | 1036 | ||
| @@ -1066,23 +1041,25 @@ const char * | |||
| 1066 | xg_add_tab (FRAME_PTR f, | 1041 | xg_add_tab (FRAME_PTR f, |
| 1067 | const char *name) | 1042 | const char *name) |
| 1068 | { | 1043 | { |
| 1069 | GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget); | 1044 | GtkNotebook *wnote; |
| 1070 | GtkWidget *wfixed = xg_add_fixed (f); | 1045 | GtkWidget *wfixed; |
| 1071 | char *key = g_object_get_data (G_OBJECT (wfixed), XG_TAB_KEY); | 1046 | char *key; |
| 1072 | int n; | 1047 | int n; |
| 1073 | GtkWidget *wlbl = xg_tab_label_widget (f, name, wfixed); | 1048 | GtkWidget *wlbl; |
| 1074 | 1049 | ||
| 1075 | BLOCK_INPUT; | 1050 | BLOCK_INPUT; |
| 1076 | 1051 | ||
| 1052 | wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget); | ||
| 1053 | wfixed = xg_add_fixed_for_tab (f); | ||
| 1054 | key = g_object_get_data (G_OBJECT (wfixed), XG_TAB_KEY); | ||
| 1055 | |||
| 1056 | wlbl = xg_tab_label_widget (f, name, wfixed); | ||
| 1077 | n = gtk_notebook_append_page (wnote, wfixed, wlbl); | 1057 | n = gtk_notebook_append_page (wnote, wfixed, wlbl); |
| 1078 | gtk_notebook_set_tab_reorderable (wnote, wfixed, TRUE); | 1058 | gtk_notebook_set_tab_reorderable (wnote, wfixed, TRUE); |
| 1079 | gtk_notebook_set_tab_detachable (wnote, wfixed, TRUE); | 1059 | gtk_notebook_set_tab_detachable (wnote, wfixed, TRUE); |
| 1080 | 1060 | ||
| 1081 | if (n > 0) | 1061 | if (n > 0) |
| 1082 | { | 1062 | gtk_notebook_set_current_page (wnote, n); |
| 1083 | gtk_notebook_set_current_page (wnote, n); | ||
| 1084 | xg_switch_page_cb (wnote, NULL, n, f); | ||
| 1085 | } | ||
| 1086 | 1063 | ||
| 1087 | UNBLOCK_INPUT; | 1064 | UNBLOCK_INPUT; |
| 1088 | return key; | 1065 | return key; |
| @@ -1129,7 +1106,6 @@ xg_delete_tab (FRAME_PTR f, | |||
| 1129 | int new_page = page_to_remove + 1; | 1106 | int new_page = page_to_remove + 1; |
| 1130 | if (new_page == pages) new_page = page_to_remove - 1; | 1107 | if (new_page == pages) new_page = page_to_remove - 1; |
| 1131 | gtk_notebook_set_current_page (wnote, new_page); | 1108 | gtk_notebook_set_current_page (wnote, new_page); |
| 1132 | xg_switch_page_cb (wnote, NULL, new_page, f); | ||
| 1133 | } | 1109 | } |
| 1134 | gtk_notebook_remove_page (wnote, page_to_remove); | 1110 | gtk_notebook_remove_page (wnote, page_to_remove); |
| 1135 | } | 1111 | } |
| @@ -1237,24 +1213,15 @@ xg_nb_window_create (GtkNotebook *source, | |||
| 1237 | gint y, | 1213 | gint y, |
| 1238 | gpointer data) | 1214 | gpointer data) |
| 1239 | { | 1215 | { |
| 1240 | struct input_event event; | ||
| 1241 | Lisp_Object frame; | ||
| 1242 | FRAME_PTR f = g_object_get_data (G_OBJECT (page), XG_FRAME_DATA); | 1216 | FRAME_PTR f = g_object_get_data (G_OBJECT (page), XG_FRAME_DATA); |
| 1243 | tabs_gc_data *oconf = g_object_get_data (G_OBJECT (page), | 1217 | GtkWidget *cur = f->output_data.x->current_tab; |
| 1244 | XG_TAB_CONFIG_KEY); | 1218 | char *key = g_object_get_data (G_OBJECT (cur), XG_TAB_KEY); |
| 1245 | XSETFRAME (frame, f); | 1219 | |
| 1246 | if (!oconf) oconf = xg_store_win_config (page, f); | 1220 | notebook_on_hold = GTK_NOTEBOOK (gtk_notebook_new ()); |
| 1247 | 1221 | store_tab_event (f, Fcons (Qtab_new_frame, | |
| 1248 | 1222 | Fcons (intern (key), Qnil)), | |
| 1249 | EVENT_INIT (event); | 1223 | x, y); |
| 1250 | event.kind = TAB_EVENT; | 1224 | return notebook_on_hold; |
| 1251 | event.frame_or_window = frame; | ||
| 1252 | event.arg = Fcons (make_number (2), Qnil); | ||
| 1253 | event.x = make_number (x); | ||
| 1254 | event.y = make_number (y); | ||
| 1255 | kbd_buffer_store_event (&event); | ||
| 1256 | |||
| 1257 | return notebook_on_hold = GTK_NOTEBOOK (gtk_notebook_new ()); | ||
| 1258 | } | 1225 | } |
| 1259 | 1226 | ||
| 1260 | int | 1227 | int |
| @@ -1294,10 +1261,7 @@ xg_set_current_tab (FRAME_PTR f, const char *key) | |||
| 1294 | } | 1261 | } |
| 1295 | 1262 | ||
| 1296 | if (page >= 0 && page < pages && page != current_page) | 1263 | if (page >= 0 && page < pages && page != current_page) |
| 1297 | { | 1264 | gtk_notebook_set_current_page (wnote, page); |
| 1298 | gtk_notebook_set_current_page (wnote, page); | ||
| 1299 | xg_switch_page_cb (wnote, NULL, page, f); | ||
| 1300 | } | ||
| 1301 | } | 1265 | } |
| 1302 | 1266 | ||
| 1303 | 1267 | ||
| @@ -1315,28 +1279,6 @@ xg_get_tab_key (FRAME_PTR f, int nr) | |||
| 1315 | return (const char *)g_object_get_data (G_OBJECT (w), XG_TAB_KEY); | 1279 | return (const char *)g_object_get_data (G_OBJECT (w), XG_TAB_KEY); |
| 1316 | } | 1280 | } |
| 1317 | 1281 | ||
| 1318 | Lisp_Object | ||
| 1319 | xg_tab_get_win_config (FRAME_PTR f, int nr) | ||
| 1320 | { | ||
| 1321 | GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget); | ||
| 1322 | GtkWidget *w; | ||
| 1323 | tabs_gc_data *conf; | ||
| 1324 | |||
| 1325 | if (!wnote || nr >= gtk_notebook_get_n_pages (wnote) | ||
| 1326 | || (w = gtk_notebook_get_nth_page (wnote, nr)) == NULL) | ||
| 1327 | return Qnil; | ||
| 1328 | |||
| 1329 | conf = g_object_get_data (G_OBJECT (w), XG_TAB_CONFIG_KEY); | ||
| 1330 | if (!conf) conf = xg_store_win_config (w, f); | ||
| 1331 | else if (w == FRAME_GTK_WIDGET (f)) | ||
| 1332 | { | ||
| 1333 | Lisp_Object frame; | ||
| 1334 | XSETFRAME (frame, f); | ||
| 1335 | conf->object = Fcurrent_window_configuration (frame); | ||
| 1336 | } | ||
| 1337 | return conf ? conf->object : Qnil; | ||
| 1338 | } | ||
| 1339 | |||
| 1340 | void | 1282 | void |
| 1341 | xg_tabs_always_show (FRAME_PTR f, int show) | 1283 | xg_tabs_always_show (FRAME_PTR f, int show) |
| 1342 | { | 1284 | { |
| @@ -1354,11 +1296,15 @@ xg_setup_notebook (FRAME_PTR f, GtkWidget *wvbox, GtkWidget *wnote) | |||
| 1354 | { | 1296 | { |
| 1355 | GtkRcStyle *style; | 1297 | GtkRcStyle *style; |
| 1356 | 1298 | ||
| 1357 | gtk_box_pack_end (GTK_BOX (wvbox), wnote, TRUE, TRUE, 0); | 1299 | gtk_box_pack_end (GTK_BOX (wvbox), wnote, FALSE, FALSE, 0); |
| 1300 | gtk_box_reorder_child (GTK_BOX (wvbox), wnote, -2); | ||
| 1301 | |||
| 1358 | g_signal_connect (G_OBJECT (wnote), "switch-page", | 1302 | g_signal_connect (G_OBJECT (wnote), "switch-page", |
| 1359 | G_CALLBACK (xg_switch_page_cb), f); | 1303 | G_CALLBACK (xg_switch_page_cb), f); |
| 1360 | g_signal_connect (G_OBJECT (wnote), "page-added", | 1304 | g_signal_connect (G_OBJECT (wnote), "page-added", |
| 1361 | G_CALLBACK (xg_page_added_cb), f); | 1305 | G_CALLBACK (xg_page_added_cb), f); |
| 1306 | g_signal_connect (G_OBJECT (wnote), "page-removed", | ||
| 1307 | G_CALLBACK (xg_page_removed_cb), f); | ||
| 1362 | 1308 | ||
| 1363 | g_object_set (G_OBJECT (wnote), "tab-border", 0, NULL); | 1309 | g_object_set (G_OBJECT (wnote), "tab-border", 0, NULL); |
| 1364 | gtk_notebook_popup_disable (GTK_NOTEBOOK (wnote)); | 1310 | gtk_notebook_popup_disable (GTK_NOTEBOOK (wnote)); |
| @@ -1389,75 +1335,29 @@ xg_enable_tabs (FRAME_PTR f, int enable) | |||
| 1389 | || (wnote != NULL && enable)) | 1335 | || (wnote != NULL && enable)) |
| 1390 | return; | 1336 | return; |
| 1391 | 1337 | ||
| 1392 | g_object_ref (G_OBJECT (wfixed)); | ||
| 1393 | if (enable) | 1338 | if (enable) |
| 1394 | { | 1339 | { |
| 1395 | GtkWidget *wlbl; | 1340 | GtkWidget *wlbl; |
| 1396 | char *key = g_object_get_data (G_OBJECT (wfixed), XG_TAB_KEY); | 1341 | char *key; |
| 1397 | 1342 | ||
| 1398 | wnote = gtk_notebook_new (); | 1343 | wnote = gtk_notebook_new (); |
| 1344 | wfixed = xg_add_fixed_for_tab (f); | ||
| 1345 | key = g_object_get_data (G_OBJECT (wfixed), XG_TAB_KEY); | ||
| 1399 | f->output_data.x->notebook_widget = wnote; | 1346 | f->output_data.x->notebook_widget = wnote; |
| 1400 | gtk_container_remove (GTK_CONTAINER (wvbox), wfixed); | ||
| 1401 | xg_setup_notebook (f, wvbox, wnote); | 1347 | xg_setup_notebook (f, wvbox, wnote); |
| 1402 | 1348 | ||
| 1403 | wlbl = xg_tab_label_widget (f, key, wfixed); | 1349 | wlbl = xg_tab_label_widget (f, key, wfixed); |
| 1404 | gtk_notebook_append_page (GTK_NOTEBOOK (wnote), wfixed, wlbl); | 1350 | gtk_notebook_append_page (GTK_NOTEBOOK (wnote), wfixed, wlbl); |
| 1405 | gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (wnote), wfixed, TRUE); | 1351 | gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (wnote), wfixed, TRUE); |
| 1406 | gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (wnote), wfixed, TRUE); | 1352 | gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (wnote), wfixed, TRUE); |
| 1407 | gtk_widget_show_all (wnote); | ||
| 1408 | } | 1353 | } |
| 1409 | else | 1354 | else |
| 1410 | { | 1355 | { |
| 1411 | xg_delete_all_tabs (f); | 1356 | xg_delete_all_tabs (f); |
| 1412 | |||
| 1413 | /* Somehow scroll bars get destroyed when the notebook widget is | ||
| 1414 | destroyed even if I take a ref to them. So remove them from | ||
| 1415 | wfixed and later put them back. */ | ||
| 1416 | GList *children = GTK_FIXED (wfixed)->children; | ||
| 1417 | GSList *todo = NULL, *iter; | ||
| 1418 | for ( ; children; children = g_list_next (children)) | ||
| 1419 | { | ||
| 1420 | GtkFixedChild *child = (GtkFixedChild*)children->data; | ||
| 1421 | if (GTK_IS_EVENT_BOX (child->widget)) | ||
| 1422 | { | ||
| 1423 | GtkFixedChild *node = xmalloc (sizeof(*node)); | ||
| 1424 | *node = *child; | ||
| 1425 | todo = g_slist_prepend (todo, node); | ||
| 1426 | } | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | for (iter = todo; iter; iter = g_slist_next (iter)) | ||
| 1430 | { | ||
| 1431 | GtkFixedChild *child = (GtkFixedChild*)iter->data; | ||
| 1432 | GtkWidget *wevbox = child->widget; | ||
| 1433 | g_object_ref (G_OBJECT (wevbox)); | ||
| 1434 | g_object_ref (G_OBJECT (gtk_bin_get_child (GTK_BIN (wevbox)))); | ||
| 1435 | gtk_container_remove (GTK_CONTAINER (wfixed), wevbox); | ||
| 1436 | } | ||
| 1437 | |||
| 1438 | gtk_container_remove (GTK_CONTAINER (wvbox), wnote); | 1357 | gtk_container_remove (GTK_CONTAINER (wvbox), wnote); |
| 1439 | gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0); | ||
| 1440 | f->output_data.x->notebook_widget = NULL; | 1358 | f->output_data.x->notebook_widget = NULL; |
| 1441 | 1359 | f->output_data.x->current_tab = NULL; | |
| 1442 | for (iter = todo; iter; iter = g_slist_next (iter)) | ||
| 1443 | { | ||
| 1444 | GtkFixedChild *child = (GtkFixedChild*)iter->data; | ||
| 1445 | GtkWidget *wevbox = child->widget; | ||
| 1446 | gtk_fixed_put (GTK_FIXED (wfixed), wevbox, child->x, child->y); | ||
| 1447 | g_object_unref (G_OBJECT (wevbox)); | ||
| 1448 | g_object_unref (G_OBJECT (gtk_bin_get_child (GTK_BIN (wevbox)))); | ||
| 1449 | free (iter->data); | ||
| 1450 | } | ||
| 1451 | |||
| 1452 | if (todo) g_slist_free (todo); | ||
| 1453 | } | 1360 | } |
| 1454 | |||
| 1455 | gtk_widget_realize (wfixed); | ||
| 1456 | gtk_widget_show_all (wfixed); | ||
| 1457 | FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed); | ||
| 1458 | FRAME_GTK_WIDGET (f) = wfixed; | ||
| 1459 | g_object_unref (G_OBJECT (wfixed)); | ||
| 1460 | gtk_widget_queue_draw (FRAME_GTK_WIDGET (f)); | ||
| 1461 | } | 1361 | } |
| 1462 | 1362 | ||
| 1463 | 1363 | ||
| @@ -1475,7 +1375,6 @@ xg_create_frame_widgets (f) | |||
| 1475 | GtkWidget *wnote = NULL; | 1375 | GtkWidget *wnote = NULL; |
| 1476 | char *title = 0; | 1376 | char *title = 0; |
| 1477 | GtkWidget *wfixed; | 1377 | GtkWidget *wfixed; |
| 1478 | tabs_gc_data *conf; | ||
| 1479 | 1378 | ||
| 1480 | BLOCK_INPUT; | 1379 | BLOCK_INPUT; |
| 1481 | 1380 | ||
| @@ -1518,6 +1417,7 @@ xg_create_frame_widgets (f) | |||
| 1518 | FRAME_GTK_OUTER_WIDGET (f) = wtop; | 1417 | FRAME_GTK_OUTER_WIDGET (f) = wtop; |
| 1519 | f->output_data.x->vbox_widget = wvbox; | 1418 | f->output_data.x->vbox_widget = wvbox; |
| 1520 | f->output_data.x->notebook_widget = wnote; | 1419 | f->output_data.x->notebook_widget = wnote; |
| 1420 | f->output_data.x->current_tab = NULL; | ||
| 1521 | 1421 | ||
| 1522 | gtk_container_add (GTK_CONTAINER (wtop), wvbox); | 1422 | gtk_container_add (GTK_CONTAINER (wtop), wvbox); |
| 1523 | 1423 | ||
| @@ -1540,20 +1440,22 @@ xg_create_frame_widgets (f) | |||
| 1540 | f->win_gravity | 1440 | f->win_gravity |
| 1541 | = gtk_window_get_gravity (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); | 1441 | = gtk_window_get_gravity (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); |
| 1542 | 1442 | ||
| 1443 | wfixed = xg_add_fixed (f); | ||
| 1444 | gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0); | ||
| 1445 | |||
| 1543 | if (wnote) | 1446 | if (wnote) |
| 1544 | { | 1447 | { |
| 1545 | xg_setup_notebook (f, wvbox, wnote); | 1448 | xg_setup_notebook (f, wvbox, wnote); |
| 1546 | 1449 | ||
| 1547 | if (!notebook_on_hold) | 1450 | if (!notebook_on_hold) |
| 1548 | xg_add_tab (f, "Page 1"); | 1451 | xg_add_tab (f, "Page_1"); |
| 1549 | 1452 | else | |
| 1550 | wfixed = gtk_notebook_get_nth_page (GTK_NOTEBOOK (wnote), 0); | 1453 | xg_page_added_cb (GTK_NOTEBOOK (wnote), |
| 1551 | } | 1454 | gtk_notebook_get_nth_page (GTK_NOTEBOOK (wnote), |
| 1552 | else | 1455 | 0), |
| 1553 | { | 1456 | 0, f); |
| 1554 | wfixed = xg_add_fixed (f); | ||
| 1555 | gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0); | ||
| 1556 | } | 1457 | } |
| 1458 | |||
| 1557 | 1459 | ||
| 1558 | 1460 | ||
| 1559 | /* Must realize the windows so the X window gets created. It is used | 1461 | /* Must realize the windows so the X window gets created. It is used |
| @@ -1563,19 +1465,10 @@ xg_create_frame_widgets (f) | |||
| 1563 | FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed); | 1465 | FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed); |
| 1564 | FRAME_GTK_WIDGET (f) = wfixed; | 1466 | FRAME_GTK_WIDGET (f) = wfixed; |
| 1565 | 1467 | ||
| 1566 | conf = g_object_get_data (G_OBJECT (wfixed), XG_TAB_CONFIG_KEY); | ||
| 1567 | if (conf | ||
| 1568 | && Fwindow_configuration_p (conf->object) && | ||
| 1569 | XFRAME (Fwindow_configuration_frame (conf->object)) != f) | ||
| 1570 | { | ||
| 1571 | Lisp_Object frame; | ||
| 1572 | XSETFRAME (frame, f); | ||
| 1573 | Fchange_window_configuration_frame (conf->object, frame); | ||
| 1574 | Fset_window_configuration (conf->object); | ||
| 1575 | } | ||
| 1576 | |||
| 1577 | notebook_on_hold = NULL; | 1468 | notebook_on_hold = NULL; |
| 1578 | 1469 | gtk_widget_show (wfixed); | |
| 1470 | gtk_widget_show (wvbox); | ||
| 1471 | |||
| 1579 | UNBLOCK_INPUT; | 1472 | UNBLOCK_INPUT; |
| 1580 | 1473 | ||
| 1581 | return 1; | 1474 | return 1; |
| @@ -2504,8 +2397,6 @@ xg_mark_data () | |||
| 2504 | if (! NILP (cb_data->help)) | 2397 | if (! NILP (cb_data->help)) |
| 2505 | mark_object (cb_data->help); | 2398 | mark_object (cb_data->help); |
| 2506 | } | 2399 | } |
| 2507 | for (iter = tabs_gc_list.next; iter; iter = iter->next) | ||
| 2508 | mark_object (((tabs_gc_data *) iter)->object); | ||
| 2509 | } | 2400 | } |
| 2510 | 2401 | ||
| 2511 | 2402 | ||
| @@ -4535,8 +4426,8 @@ find_rtl_image (f, image, rtl) | |||
| 4535 | Lisp_Object rtl_image = PROP (TOOL_BAR_ITEM_IMAGES); | 4426 | Lisp_Object rtl_image = PROP (TOOL_BAR_ITEM_IMAGES); |
| 4536 | if (!NILP (file = file_for_image (rtl_image))) | 4427 | if (!NILP (file = file_for_image (rtl_image))) |
| 4537 | { | 4428 | { |
| 4538 | file = call1 (intern ("file-name-sans-extension"), | 4429 | file = call1 (Qfile_sans_ext, |
| 4539 | Ffile_name_nondirectory (file)); | 4430 | Ffile_name_nondirectory (file)); |
| 4540 | if (EQ (Fequal (file, rtl_name), Qt)) | 4431 | if (EQ (Fequal (file, rtl_name), Qt)) |
| 4541 | { | 4432 | { |
| 4542 | image = rtl_image; | 4433 | image = rtl_image; |
| @@ -4939,7 +4830,6 @@ xg_initialize () | |||
| 4939 | id_to_widget.max_size = id_to_widget.used = 0; | 4830 | id_to_widget.max_size = id_to_widget.used = 0; |
| 4940 | id_to_widget.widgets = 0; | 4831 | id_to_widget.widgets = 0; |
| 4941 | xg_tab_nr = 1; | 4832 | xg_tab_nr = 1; |
| 4942 | tabs_gc_list.prev = tabs_gc_list.next = 0; | ||
| 4943 | xg_always_show_tabs = 0; | 4833 | xg_always_show_tabs = 0; |
| 4944 | 4834 | ||
| 4945 | /* Remove F10 as a menu accelerator, it does not mix well with Emacs key | 4835 | /* Remove F10 as a menu accelerator, it does not mix well with Emacs key |
| @@ -4979,6 +4869,24 @@ xg_initialize () | |||
| 4979 | "widget \"*\" style \"noborder\"\n"); | 4869 | "widget \"*\" style \"noborder\"\n"); |
| 4980 | } | 4870 | } |
| 4981 | 4871 | ||
| 4872 | void | ||
| 4873 | syms_of_gtkutil () | ||
| 4874 | { | ||
| 4875 | Qtab_new_frame = intern_c_string ("tab-new-frame"); | ||
| 4876 | staticpro (&Qtab_new_frame); | ||
| 4877 | Qtab_changed = intern_c_string ("tab-changed"); | ||
| 4878 | staticpro (&Qtab_changed); | ||
| 4879 | Qtab_added = intern_c_string ("tab-added"); | ||
| 4880 | staticpro (&Qtab_added); | ||
| 4881 | Qtab_removed = intern_c_string ("tab-removed"); | ||
| 4882 | staticpro (&Qtab_removed); | ||
| 4883 | Qfile_sans_ext = intern_c_string ("file-name-sans-extension"); | ||
| 4884 | staticpro (&Qfile_sans_ext); | ||
| 4885 | Qx_gtk_map_stock = intern_c_string ("x-gtk-map-stock"); | ||
| 4886 | staticpro (&Qx_gtk_map_stock); | ||
| 4887 | } | ||
| 4888 | |||
| 4889 | |||
| 4982 | #endif /* USE_GTK */ | 4890 | #endif /* USE_GTK */ |
| 4983 | 4891 | ||
| 4984 | /* arch-tag: fe7104da-bc1e-4aba-9bd1-f349c528f7e3 | 4892 | /* arch-tag: fe7104da-bc1e-4aba-9bd1-f349c528f7e3 |
diff --git a/src/gtkutil.h b/src/gtkutil.h index b005498e843..a08d387809b 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h | |||
| @@ -135,6 +135,7 @@ extern char *xg_get_file_name P_ ((FRAME_PTR f, | |||
| 135 | int only_dir_p)); | 135 | int only_dir_p)); |
| 136 | 136 | ||
| 137 | extern char *xg_get_font_name P_ ((FRAME_PTR f, char *)); | 137 | extern char *xg_get_font_name P_ ((FRAME_PTR f, char *)); |
| 138 | |||
| 138 | extern const char *xg_add_tab P_ ((FRAME_PTR f, const char *name)); | 139 | extern const char *xg_add_tab P_ ((FRAME_PTR f, const char *name)); |
| 139 | extern void xg_delete_tab P_ ((FRAME_PTR f, const char *name)); | 140 | extern void xg_delete_tab P_ ((FRAME_PTR f, const char *name)); |
| 140 | extern void xg_delete_all_tabs P_ ((FRAME_PTR f)); | 141 | extern void xg_delete_all_tabs P_ ((FRAME_PTR f)); |
| @@ -146,8 +147,6 @@ extern int xg_current_tab P_ ((FRAME_PTR f)); | |||
| 146 | extern const char *xg_get_tab_key P_ ((FRAME_PTR f, int nr)); | 147 | extern const char *xg_get_tab_key P_ ((FRAME_PTR f, int nr)); |
| 147 | extern void xg_set_current_tab P_ ((FRAME_PTR f, const char *key)); | 148 | extern void xg_set_current_tab P_ ((FRAME_PTR f, const char *key)); |
| 148 | extern void xg_enable_tabs P_ ((FRAME_PTR f, int enable)); | 149 | extern void xg_enable_tabs P_ ((FRAME_PTR f, int enable)); |
| 149 | |||
| 150 | extern Lisp_Object xg_tab_get_win_config P_ ((FRAME_PTR f, int nr)); | ||
| 151 | extern void xg_tabs_always_show P_ ((FRAME_PTR f, int show)); | 150 | extern void xg_tabs_always_show P_ ((FRAME_PTR f, int show)); |
| 152 | 151 | ||
| 153 | 152 | ||
diff --git a/src/lisp.h b/src/lisp.h index 7f5d5df66c6..b7920a74c76 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -2636,6 +2636,9 @@ extern int pos_visible_p P_ ((struct window *, int, int *, | |||
| 2636 | /* Defined in xsettings.c */ | 2636 | /* Defined in xsettings.c */ |
| 2637 | extern void syms_of_xsettings P_ ((void)); | 2637 | extern void syms_of_xsettings P_ ((void)); |
| 2638 | 2638 | ||
| 2639 | /* Defined in gtkutil.c */ | ||
| 2640 | extern void syms_of_gtkutil P_ ((void)); | ||
| 2641 | |||
| 2639 | /* Defined in vm-limit.c. */ | 2642 | /* Defined in vm-limit.c. */ |
| 2640 | extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ())); | 2643 | extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ())); |
| 2641 | 2644 | ||
diff --git a/src/window.c b/src/window.c index 4874b1c7ff6..89f5e312ccb 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -6066,6 +6066,8 @@ DEFUN ("change-window-configuration-frame", Fchange_window_configuration_frame, | |||
| 6066 | Vwindow_list = Qnil; | 6066 | Vwindow_list = Qnil; |
| 6067 | 6067 | ||
| 6068 | #undef MAP_WINDOW | 6068 | #undef MAP_WINDOW |
| 6069 | |||
| 6070 | return config; | ||
| 6069 | } | 6071 | } |
| 6070 | 6072 | ||
| 6071 | DEFUN ("buffers-in-window-configuration", Fbuffers_in_window_configuration, | 6073 | DEFUN ("buffers-in-window-configuration", Fbuffers_in_window_configuration, |
diff --git a/src/xfns.c b/src/xfns.c index b192263e87b..3b40f767544 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -5903,7 +5903,7 @@ DEFUN ("tab-new", Ftab_new, | |||
| 5903 | If LABEL is nil, use current buffer name. | 5903 | If LABEL is nil, use current buffer name. |
| 5904 | FRAME nil means use the selected frame. | 5904 | FRAME nil means use the selected frame. |
| 5905 | 5905 | ||
| 5906 | Returns the key for the tab, which can be passed to `tab-delete'. */) | 5906 | Returns the key for the tab ( symbol), which can be passed to `tab-delete'. */) |
| 5907 | (label, frame) | 5907 | (label, frame) |
| 5908 | Lisp_Object label, frame; | 5908 | Lisp_Object label, frame; |
| 5909 | { | 5909 | { |
| @@ -5925,7 +5925,7 @@ Returns the key for the tab, which can be passed to `tab-delete'. */) | |||
| 5925 | key = xg_add_tab (f, SDATA (label)); | 5925 | key = xg_add_tab (f, SDATA (label)); |
| 5926 | UNBLOCK_INPUT; | 5926 | UNBLOCK_INPUT; |
| 5927 | 5927 | ||
| 5928 | return make_string (key, strlen (key)); | 5928 | return intern (key); |
| 5929 | } | 5929 | } |
| 5930 | 5930 | ||
| 5931 | DEFUN ("tab-delete", Ftab_delete, | 5931 | DEFUN ("tab-delete", Ftab_delete, |
| @@ -5938,11 +5938,11 @@ FRAME nil means use the selected frame. */) | |||
| 5938 | { | 5938 | { |
| 5939 | FRAME_PTR f = check_x_frame (frame); | 5939 | FRAME_PTR f = check_x_frame (frame); |
| 5940 | if (f->no_tabs) return Qnil; | 5940 | if (f->no_tabs) return Qnil; |
| 5941 | if (!NILP (key) && !STRINGP (key)) | 5941 | if (!NILP (key) && !SYMBOLP (key)) |
| 5942 | error ("Key is not string or nil"); | 5942 | error ("Key is not a symbol or nil"); |
| 5943 | 5943 | ||
| 5944 | BLOCK_INPUT; | 5944 | BLOCK_INPUT; |
| 5945 | xg_delete_tab (f, NILP (key) ? NULL : SDATA (key)); | 5945 | xg_delete_tab (f, NILP (key) ? NULL : SDATA (SYMBOL_NAME (key))); |
| 5946 | UNBLOCK_INPUT; | 5946 | UNBLOCK_INPUT; |
| 5947 | 5947 | ||
| 5948 | return Qnil; | 5948 | return Qnil; |
| @@ -6056,9 +6056,7 @@ DEFUN ("tab-configuration", Ftab_configuration, | |||
| 6056 | Stab_configuration, 0, 1, 0, | 6056 | Stab_configuration, 0, 1, 0, |
| 6057 | doc: /* Return the tab configuration on FRAME. | 6057 | doc: /* Return the tab configuration on FRAME. |
| 6058 | FRAME nil means use the selected frame. | 6058 | FRAME nil means use the selected frame. |
| 6059 | Returns an alist where each element is of type (KEY WINDOWCONFIG). | 6059 | Returns an list where each element is a symbol representing a tab. |
| 6060 | KEY is the name of the tab as returned by `tab_new´. | ||
| 6061 | WINDOWCONFIG is the window configuration for the tab. | ||
| 6062 | 6060 | ||
| 6063 | If FRAME is a tab-less frame, returns nil. */) | 6061 | If FRAME is a tab-less frame, returns nil. */) |
| 6064 | (frame) | 6062 | (frame) |
| @@ -6072,12 +6070,10 @@ If FRAME is a tab-less frame, returns nil. */) | |||
| 6072 | nr = xg_tab_count (f); | 6070 | nr = xg_tab_count (f); |
| 6073 | for (i = 0; i < nr; ++i) | 6071 | for (i = 0; i < nr; ++i) |
| 6074 | { | 6072 | { |
| 6075 | Lisp_Object wc = xg_tab_get_win_config (f, i); | ||
| 6076 | const char *key = xg_get_tab_key (f, i); | 6073 | const char *key = xg_get_tab_key (f, i); |
| 6077 | 6074 | ||
| 6078 | cc = Fcons (Fcons (key ? make_string (key, strlen (key)) : Qnil, | 6075 | if (key) |
| 6079 | NILP (wc) ? wc : Fcons (wc, Qnil)), | 6076 | cc = Fcons (intern (key), cc); |
| 6080 | cc); | ||
| 6081 | } | 6077 | } |
| 6082 | 6078 | ||
| 6083 | return cc; | 6079 | return cc; |
| @@ -6098,7 +6094,7 @@ If FRAME is a tab-less frame, returns nil. */) | |||
| 6098 | if (f->no_tabs) return Qnil; | 6094 | if (f->no_tabs) return Qnil; |
| 6099 | nr = xg_current_tab (f); | 6095 | nr = xg_current_tab (f); |
| 6100 | const char *key = xg_get_tab_key (f, nr); | 6096 | const char *key = xg_get_tab_key (f, nr); |
| 6101 | return key ? make_string (key, strlen (key)) : Qnil; | 6097 | return key ? intern (key) : Qnil; |
| 6102 | } | 6098 | } |
| 6103 | 6099 | ||
| 6104 | DEFUN ("tab-show", Ftab_show, | 6100 | DEFUN ("tab-show", Ftab_show, |
| @@ -6111,10 +6107,10 @@ If FRAME is a tab-less frame or the key doesn't refer to a tab, do nothing. */) | |||
| 6111 | { | 6107 | { |
| 6112 | FRAME_PTR f = check_x_frame (frame); | 6108 | FRAME_PTR f = check_x_frame (frame); |
| 6113 | if (f->no_tabs) return Qnil; | 6109 | if (f->no_tabs) return Qnil; |
| 6114 | CHECK_STRING (key); | 6110 | CHECK_SYMBOL (key); |
| 6115 | 6111 | ||
| 6116 | BLOCK_INPUT; | 6112 | BLOCK_INPUT; |
| 6117 | xg_set_current_tab (f, SDATA (key)); | 6113 | xg_set_current_tab (f, SDATA (SYMBOL_NAME (key))); |
| 6118 | UNBLOCK_INPUT; | 6114 | UNBLOCK_INPUT; |
| 6119 | 6115 | ||
| 6120 | return Qnil; | 6116 | return Qnil; |
diff --git a/src/xterm.c b/src/xterm.c index 54cac40e091..91a65fc32cb 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -325,9 +325,6 @@ static Lisp_Object Qlatin_1; | |||
| 325 | #ifdef USE_GTK | 325 | #ifdef USE_GTK |
| 326 | /* The name of the Emacs icon file. */ | 326 | /* The name of the Emacs icon file. */ |
| 327 | static Lisp_Object xg_default_icon_file; | 327 | static Lisp_Object xg_default_icon_file; |
| 328 | |||
| 329 | /* Used in gtkutil.c. */ | ||
| 330 | Lisp_Object Qx_gtk_map_stock; | ||
| 331 | #endif | 328 | #endif |
| 332 | 329 | ||
| 333 | /* Used in x_flush. */ | 330 | /* Used in x_flush. */ |
| @@ -9265,7 +9262,7 @@ x_make_frame_visible (f) | |||
| 9265 | } | 9262 | } |
| 9266 | #else /* not USE_X_TOOLKIT */ | 9263 | #else /* not USE_X_TOOLKIT */ |
| 9267 | #ifdef USE_GTK | 9264 | #ifdef USE_GTK |
| 9268 | gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); | 9265 | gtk_widget_show (FRAME_GTK_OUTER_WIDGET (f)); |
| 9269 | gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); | 9266 | gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); |
| 9270 | #else | 9267 | #else |
| 9271 | if (FRAME_X_EMBEDDED_P (f)) | 9268 | if (FRAME_X_EMBEDDED_P (f)) |
| @@ -10970,9 +10967,6 @@ syms_of_xterm () | |||
| 10970 | #ifdef USE_GTK | 10967 | #ifdef USE_GTK |
| 10971 | xg_default_icon_file = make_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg"); | 10968 | xg_default_icon_file = make_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg"); |
| 10972 | staticpro (&xg_default_icon_file); | 10969 | staticpro (&xg_default_icon_file); |
| 10973 | |||
| 10974 | Qx_gtk_map_stock = intern_c_string ("x-gtk-map-stock"); | ||
| 10975 | staticpro (&Qx_gtk_map_stock); | ||
| 10976 | #endif | 10970 | #endif |
| 10977 | 10971 | ||
| 10978 | DEFVAR_BOOL ("x-use-underline-position-properties", | 10972 | DEFVAR_BOOL ("x-use-underline-position-properties", |
diff --git a/src/xterm.h b/src/xterm.h index 09be1626c19..1925210b623 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -477,6 +477,8 @@ struct x_output | |||
| 477 | GtkWidget *vbox_widget; | 477 | GtkWidget *vbox_widget; |
| 478 | /* The notebook (i.e. tab) widget. */ | 478 | /* The notebook (i.e. tab) widget. */ |
| 479 | GtkWidget *notebook_widget; | 479 | GtkWidget *notebook_widget; |
| 480 | /* The current note book child. */ | ||
| 481 | GtkWidget *current_tab; | ||
| 480 | /* The menubar in this frame. */ | 482 | /* The menubar in this frame. */ |
| 481 | GtkWidget *menubar_widget; | 483 | GtkWidget *menubar_widget; |
| 482 | /* The tool bar in this frame */ | 484 | /* The tool bar in this frame */ |