summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan D <jan.h.d@swipnet.se>2010-05-16 20:49:26 +0200
committerJan D <jan.h.d@swipnet.se>2010-05-16 20:49:26 +0200
commitdf68b7080ffc59c18f3289a3d4eb157f7c111454 (patch)
tree49e8c75ac59e77613bd18826319d2f65b8bd2ce0
parenta2b9f1182d6159061079fa0b480ec9ff81cc95f1 (diff)
downloademacs-gtk-tabs.tar.gz
Tab keys are symbols.gtk-tabs
Tab switch is in elisp. Save/restore point in tabs also.
-rw-r--r--lisp/native-tabs.el134
-rw-r--r--src/emacs.c3
-rw-r--r--src/gtkutil.c384
-rw-r--r--src/gtkutil.h3
-rw-r--r--src/lisp.h3
-rw-r--r--src/window.c2
-rw-r--r--src/xfns.c26
-rw-r--r--src/xterm.c8
-rw-r--r--src/xterm.h2
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 @@
(define-key map "\C-x70" 'tab-delete)
(define-key map "\C-x71" 'tab-delete-other)
(define-key map "\C-x72" 'tab-new)
- (define-key map "\C-x73" 'switch-to-buffer-tab)
+ (define-key map "\C-x73" 'switch-to-buffer-in-tab)
(define-key map "\C-x7b" 'switch-to-buffer-other-tab)
(define-key map "\C-x7f" 'find-file-new-tab)
(define-key map "\C-x7o" 'tab-next)
@@ -58,16 +58,34 @@ Keyboard commands for tabs are:
:keymap tab-mode-map
(modify-all-frames-parameters (list (cons 'disable-tabs (not tab-mode)))))
-(declare-function tab-new "xfns.c" ())
-(declare-function tab-delete "xfns.c" ())
-(declare-function tab-delete-other "xfns.c" ())
-(declare-function tab-next "xfns.c" ())
-(declare-function tab-previous "xfns.c" ())
-(declare-function tab-nr-of-tabs "xfns.c" ())
-(declare-function tab-configuration "xfns.c" ())
-(declare-function tab-current "xfns.c" ())
-(declare-function tab-show "xfns.c" ())
-(declare-function tab-enable "xfns.c" ())
+(declare-function tab-new "xfns.c" (&optional label frame))
+(declare-function tab-delete "xfns.c" (&optional label frame))
+(declare-function tab-delete-other "xfns.c" (&optional frame))
+(declare-function tab-next "xfns.c" (&optional frame))
+(declare-function tab-previous "xfns.c" (&optional frame))
+(declare-function tab-nr-of-tabs "xfns.c" (&optional frame))
+(declare-function tab-current "xfns.c" (&optional frame))
+(declare-function tab-show "xfns.c" (key &optional frame))
+(declare-function tab-enable "xfns.c" (enable &optional frame))
+
+(defun current-tab-window-config ()
+ (list (current-window-configuration) (point-marker)))
+
+(defun window-tab-config-frame (config)
+ (if (and (consp config) (window-configuration-p (car config)))
+ (window-configuration-frame (car config))
+ nil))
+
+(defun set-tab-window-config (config)
+ (and (consp config) (window-configuration-p (car config))
+ (set-window-configuration (car config))
+ (goto-char (cadr config))))
+
+(defun change-tab-window-config-frame (config frame)
+ (if (and (consp config) (window-configuration-p (car config)))
+ (list (change-window-configuration-frame (car config) frame)
+ (cadr config))
+ config))
(defun find-file-new-tab (filename &optional wildcards)
"Edit file FILENAME, in a new tab.
@@ -83,16 +101,20 @@ expand wildcards (if any) and visit multiple files."
(interactive
(find-file-read-args "Find file in new tab: "
(confirm-nonexistent-file-or-buffer)))
- (let ((value (find-file-noselect filename nil nil wildcards)))
- (if (not (null (tab-new)))
- (progn
- (delete-other-windows)
- (if (listp value)
- (progn
- (setq value (nreverse value))
- (cons (switch-to-buffer (car value))
- (mapcar 'switch-to-buffer (cdr value))))
- (switch-to-buffer value))))))
+ (save-window-excursion
+ (let* ((value (find-file-noselect filename nil nil wildcards))
+ (newtab (tab-new)))
+ (if newtab
+ (progn
+ (delete-other-windows)
+ (if (listp value)
+ (progn
+ (setq value (nreverse value))
+ (cons (switch-to-buffer (car value))
+ (dolist 'switch-to-buffer (cdr value))))
+ (switch-to-buffer value))
+ (put newtab 'winconfig (current-tab-window-config)))))))
+
(defun switch-to-buffer-other-tab (buffer-or-name &optional norecord)
"Switch to buffer BUFFER-OR-NAME in another tab.
@@ -123,8 +145,8 @@ documentation for additional customization information."
(delete-other-windows)))))
-(defun display-existing-buffer-in-tab (buffer-or-name &optional frame)
- "Switch to a tab that shows BUFFER-OR-NAME on FRAME.
+(defun find-tab-for-existing-buffer (buffer-or-name &optional frame)
+ "Find a tab that shows BUFFER-OR-NAME on FRAME.
FRAME nil means selected frame.
Returns the key for the tab switch to, or nil if no tab displays
@@ -136,21 +158,19 @@ BUFFER-OR-NAME."
(tab-key))
(while (and tabs (null tab-key))
(let* ((elt (car tabs))
- (winconf (cadr elt))
+ (winconf (get elt 'winconfig))
(buffers (buffers-in-window-configuration winconf)))
(if (memq buffer buffers)
- (setq tab-key (car elt))
+ (setq tab-key elt)
(setq tabs (cdr tabs)))))
- (if (and tab-key (not (equal tab-key (tab-current frame))))
- (progn
- (tab-show tab-key frame)
- tab-key)
- nil)))
+ tab-key))
-(defun switch-to-buffer-tab (buffer-or-name &optional frame)
+(defun switch-to-buffer-in-tab (buffer-or-name &optional frame)
(interactive "BSwitch to buffer:\nP")
- (if (not (display-existing-buffer-in-tab buffer-or-name frame))
- (switch-to-buffer buffer-or-name)))
+ (let ((tab (find-tab-for-existing-buffer buffer-or-name frame)))
+ (if tab
+ (tab-show tab frame)
+ (switch-to-buffer buffer-or-name))))
(defun handle-tab-event (event)
"Handle tab-event to change tabs on the frame in EVENT."
@@ -161,23 +181,35 @@ BUFFER-OR-NAME."
(frame (car n1))
(x (car (cdr n1)))
(y (cdr (cdr n1))))
- (if (eq type 2) ;; // A tab is dropped from another frame.
- (let ((top y)
- (left x)
- (width (frame-pixel-width frame))
- (height (frame-pixel-height frame))
- (dw (x-display-pixel-width frame))
- (dh (x-display-pixel-height frame)))
- (if (< dw (+ left width))
- (setq left (- dw width)))
- (if (< dh (+ top height))
- (setq top (- dh height)))
- (make-frame
- (list (cons 'width (frame-parameter frame 'width))
- (cons 'height(frame-parameter frame 'height))
- (cons 'top top)
- (cons 'left left)))))))
-
-(define-key special-event-map [tab-event] 'handle-tab-event)
+ (cond ((eq type 'tab-new-frame) ;; // A tab is dropped to the background.
+ (let ((tab (car (cdr n2)))
+ (top y)
+ (left x)
+ (width (frame-pixel-width frame))
+ (height (frame-pixel-height frame))
+ (dw (x-display-pixel-width frame))
+ (dh (x-display-pixel-height frame)))
+ (if (< dw (+ left width))
+ (setq left (- dw width)))
+ (if (< dh (+ top height))
+ (setq top (- dh height)))
+ (make-frame
+ (list (cons 'width (frame-parameter frame 'width))
+ (cons 'height(frame-parameter frame 'height))
+ (cons 'top top)
+ (cons 'left left)))))
+
+ ((eq type 'tab-changed)
+ (let* ((newtab (car (cdr n2)))
+ (newcfg (get newtab 'winconfig))
+ (oldtab (cdr (cdr n2))))
+ (if oldtab (put oldtab 'winconfig (current-tab-window-config)))
+ (if newcfg (set-tab-window-config
+ (if (eq (window-tab-config-frame newcfg) frame)
+ newcfg
+ (put newtab 'winconfig
+ (change-tab-window-config-frame newcfg frame))))
+ (delete-other-windows)))))))
+(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)
syms_of_xmenu ();
syms_of_fontset ();
syms_of_xsettings ();
+#ifdef USE_GTK
+ syms_of_gtkutil ();
+#endif
#ifdef HAVE_X_SM
syms_of_xsmfns ();
#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/>. */
/* Avoid "differ in sign" warnings */
#define SSDATA(x) ((char *) SDATA (x))
+static Lisp_Object Qfile_sans_ext, Qx_gtk_map_stock;
+
/***********************************************************************
Display handling functions
@@ -758,34 +760,31 @@ xg_pix_to_gcolor (w, pixel, c)
Tab functions
***********************************************************************/
#define XG_TAB_KEY "emacs-tab-key"
-#define XG_TAB_CONFIG_KEY "emacs-tab-config-key"
+
static int xg_tab_nr;
-static xg_list_node tabs_gc_list;
static GtkNotebook* notebook_on_hold;
+static Lisp_Object Qtab_new_frame, Qtab_changed, Qtab_added, Qtab_removed;
-/* If 1, show tabs even if there is only one tab. */
+/* If non-zero, show tabs even if there is only one tab. */
static int xg_always_show_tabs;
-typedef struct
-{
- xg_list_node ptrs;
- Lisp_Object object;
-} tabs_gc_data;
-
-
-/* Store the current window configuration for frame F in widget W. */
-
-static tabs_gc_data *
-xg_store_win_config (GtkWidget *w, FRAME_PTR f)
+static void
+store_tab_event (FRAME_PTR f,
+ Lisp_Object arg,
+ int x,
+ int y)
{
+ struct input_event event;
Lisp_Object frame;
- tabs_gc_data *conf = xmalloc (sizeof(*conf));
XSETFRAME (frame, f);
- g_object_set_data (G_OBJECT (w), XG_TAB_CONFIG_KEY, conf);
- xg_list_insert (&tabs_gc_list, &conf->ptrs);
- conf->object = Fcurrent_window_configuration (frame);
- return conf;
+ EVENT_INIT (event);
+ event.kind = TAB_EVENT;
+ event.frame_or_window = frame;
+ event.arg = arg;
+ event.x = make_number (x);
+ event.y = make_number (y);
+ kbd_buffer_store_event (&event);
}
static void
@@ -798,17 +797,24 @@ xg_check_show_tabs (FRAME_PTR f,
if ((shown && !should_show) || (!shown && should_show))
{
- GtkRequisition req;
int oldheight, row_add = 0;
+ if (should_show)
+ gtk_widget_show_all (GTK_WIDGET (wnote));
+ else
+ gtk_widget_hide (GTK_WIDGET (wnote));
gtk_notebook_set_show_tabs (wnote, should_show);
oldheight = FRAME_TABS_HEIGHT (f);
- gtk_widget_size_request (f->output_data.x->notebook_widget, &req);
- if (req.height > FRAME_PIXEL_HEIGHT (f))
- FRAME_TABS_HEIGHT (f) = req.height - FRAME_PIXEL_HEIGHT (f);
+ if (should_show)
+ {
+ GtkRequisition req;
+ gtk_widget_size_request (f->output_data.x->notebook_widget, &req);
+ FRAME_TABS_HEIGHT (f) = req.height;
+ }
else
FRAME_TABS_HEIGHT (f) = 0;
+
x_wm_set_size_hint (f, 0, 0);
/* Try to minimize resize, when adding/removing the tabs, add some text
@@ -829,8 +835,7 @@ xg_check_show_tabs (FRAME_PTR f,
}
}
-/* Callback called when a new tab has been added.
- Handle the case when a page has been dropped from another frame. */
+/* Callback called when a new tab has been added. */
static void
xg_page_added_cb (GtkNotebook *notebook,
@@ -839,19 +844,37 @@ xg_page_added_cb (GtkNotebook *notebook,
gpointer user_data)
{
FRAME_PTR f = (FRAME_PTR) user_data;
- tabs_gc_data *conf = g_object_get_data (G_OBJECT (child), XG_TAB_CONFIG_KEY);
+ char *newkey = g_object_get_data (G_OBJECT (child), XG_TAB_KEY);
+ GtkWidget *old = f->output_data.x->current_tab;
- /* Dropped from another frame? */
- if (conf
- && Fwindow_configuration_p (conf->object) &&
- XFRAME (Fwindow_configuration_frame (conf->object)) != f)
+ store_tab_event (f, Fcons (Qtab_added,
+ Fcons (intern (newkey), Qnil)),
+ 0, 0);
+ if (old == NULL)
{
- Lisp_Object frame;
- XSETFRAME (frame, f);
- Fchange_window_configuration_frame (conf->object, frame);
+ old = child;
+ store_tab_event (f, Fcons (Qtab_changed, Fcons (intern (newkey), Qnil)),
+ 0, 0);
}
}
+/* Callback called when a new tab has been added. */
+
+static void
+xg_page_removed_cb (GtkNotebook *notebook,
+ GtkWidget *child,
+ guint page_num,
+ gpointer user_data)
+{
+ FRAME_PTR f = (FRAME_PTR) user_data;
+ char *key = g_object_get_data (G_OBJECT (child), XG_TAB_KEY);
+
+ store_tab_event (f, Fcons (Qtab_removed,
+ Fcons (intern (key), Qnil)),
+ 0, 0);
+
+}
+
/* Callback called when the current tab changes. */
static void
@@ -860,75 +883,26 @@ xg_switch_page_cb (GtkNotebook *wnote,
guint page_num,
gpointer user_data)
{
- BLOCK_INPUT;
GtkWidget *w = gtk_notebook_get_nth_page (wnote, page_num);
FRAME_PTR f = (FRAME_PTR) user_data;
+ GtkWidget *old = f->output_data.x->current_tab;
- if (FRAME_GTK_WIDGET (f) && w != FRAME_GTK_WIDGET (f))
+ BLOCK_INPUT;
+ if (w != old)
{
- GtkWidget *old = FRAME_GTK_WIDGET (f);
- GList *children = old ? GTK_FIXED (old)->children : NULL;
- GSList *todo = NULL, *iter;
char *key = g_object_get_data (G_OBJECT (w), XG_TAB_KEY);
- tabs_gc_data *conf = g_object_get_data (G_OBJECT (w), XG_TAB_CONFIG_KEY);
-
- if (!w->window) gtk_widget_realize (w);
- FRAME_GTK_WIDGET (f) = w;
- FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (w);
- for ( ; children; children = g_list_next (children))
- {
- GtkFixedChild *child = (GtkFixedChild*)children->data;
- if (GTK_IS_EVENT_BOX (child->widget))
- {
- GtkFixedChild *node = xmalloc (sizeof(*node));
- *node = *child;
- todo = g_slist_prepend (todo, node);
- }
- }
-
- for (iter = todo; iter; iter = g_slist_next (iter))
- {
- GtkFixedChild *child = (GtkFixedChild*)iter->data;
- GtkWidget *wevbox = child->widget;
- g_object_ref (G_OBJECT (wevbox));
- gtk_container_remove (GTK_CONTAINER (old), wevbox);
- gtk_fixed_put (GTK_FIXED (w), wevbox, child->x, child->y);
- g_object_unref (G_OBJECT (wevbox));
- xfree (child);
- iter->data = NULL;
- }
- if (todo) g_slist_free (todo);
-
- SET_FRAME_GARBAGED (f);
- cancel_mouse_face (f);
-
- if (old)
- {
- struct input_event event;
- Lisp_Object frame;
-
- char *oldkey = g_object_get_data (G_OBJECT (old), XG_TAB_KEY);
- tabs_gc_data *oconf = g_object_get_data (G_OBJECT (old),
- XG_TAB_CONFIG_KEY);
- if (!oconf)
- oconf = xg_store_win_config (old, f);
-
- XSETFRAME (frame, f);
-
- EVENT_INIT (event);
- event.kind = TAB_EVENT;
- event.frame_or_window = frame;
- event.arg = Fcons (make_number (1),
- Fcons (make_string (key, strlen (key)),
- make_string (oldkey, strlen (oldkey))));
- kbd_buffer_store_event (&event);
- }
-
- if (conf)
- Fset_window_configuration (conf->object);
- else
- Fdelete_other_windows (Qnil);
+ char *oldkey = old
+ ? g_object_get_data (G_OBJECT (old), XG_TAB_KEY)
+ : NULL;
+
+ store_tab_event (f,
+ Fcons (Qtab_changed,
+ Fcons (intern (key),
+ oldkey ? intern (oldkey) : Qnil)),
+ 0, 0);
}
+
+ f->output_data.x->current_tab = w;
xg_check_show_tabs (f, wnote);
UNBLOCK_INPUT;
}
@@ -938,12 +912,6 @@ xg_fixed_destroy_cb (GtkWidget *widget,
gpointer client_data)
{
char *key = g_object_get_data (G_OBJECT (widget), XG_TAB_KEY);
- tabs_gc_data *conf = g_object_get_data (G_OBJECT (widget), XG_TAB_CONFIG_KEY);
- if (conf)
- {
- xg_list_remove (&tabs_gc_list, &conf->ptrs);
- xfree (conf);
- }
xfree (key);
}
@@ -1006,8 +974,6 @@ xg_add_fixed (FRAME_PTR f)
GtkWidget *wfixed = gtk_fixed_new ();
GdkColor bg;
GtkRcStyle *style;
- char buf[64];
- char *key;
gtk_widget_set_name (wfixed, SSDATA (Vx_resource_name));
g_object_set_data (G_OBJECT (wfixed), XG_FRAME_DATA, (gpointer)f);
@@ -1046,16 +1012,25 @@ xg_add_fixed (FRAME_PTR f)
gtk_widget_modify_style (wfixed, style);
gtk_widget_show (wfixed);
- /* Not really needed on tab-less frames, but set it anyway so enabling
- of tabs later becomes easier. */
- sprintf (buf, "Page %d", xg_tab_nr++);
+ return wfixed;
+}
+
+static GtkWidget *
+xg_add_fixed_for_tab (FRAME_PTR f)
+{
+ char buf[64];
+ GtkWidget *wfixed = gtk_fixed_new ();
+ char *key;
+
+ gtk_widget_set_size_request (wfixed, 0, 0);
+ g_object_set_data (G_OBJECT (wfixed), XG_FRAME_DATA, (gpointer)f);
+ sprintf (buf, "Page_%d", xg_tab_nr++);
key = xstrdup (buf);
g_object_set_data (G_OBJECT (wfixed), XG_TAB_KEY, key);
g_signal_connect (G_OBJECT (wfixed),
"destroy",
G_CALLBACK (xg_fixed_destroy_cb), 0);
-
-
+ gtk_widget_show (wfixed);
return wfixed;
}
@@ -1066,23 +1041,25 @@ const char *
xg_add_tab (FRAME_PTR f,
const char *name)
{
- GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
- GtkWidget *wfixed = xg_add_fixed (f);
- char *key = g_object_get_data (G_OBJECT (wfixed), XG_TAB_KEY);
+ GtkNotebook *wnote;
+ GtkWidget *wfixed;
+ char *key;
int n;
- GtkWidget *wlbl = xg_tab_label_widget (f, name, wfixed);
+ GtkWidget *wlbl;
BLOCK_INPUT;
+ wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
+ wfixed = xg_add_fixed_for_tab (f);
+ key = g_object_get_data (G_OBJECT (wfixed), XG_TAB_KEY);
+
+ wlbl = xg_tab_label_widget (f, name, wfixed);
n = gtk_notebook_append_page (wnote, wfixed, wlbl);
gtk_notebook_set_tab_reorderable (wnote, wfixed, TRUE);
gtk_notebook_set_tab_detachable (wnote, wfixed, TRUE);
if (n > 0)
- {
- gtk_notebook_set_current_page (wnote, n);
- xg_switch_page_cb (wnote, NULL, n, f);
- }
+ gtk_notebook_set_current_page (wnote, n);
UNBLOCK_INPUT;
return key;
@@ -1129,7 +1106,6 @@ xg_delete_tab (FRAME_PTR f,
int new_page = page_to_remove + 1;
if (new_page == pages) new_page = page_to_remove - 1;
gtk_notebook_set_current_page (wnote, new_page);
- xg_switch_page_cb (wnote, NULL, new_page, f);
}
gtk_notebook_remove_page (wnote, page_to_remove);
}
@@ -1237,24 +1213,15 @@ xg_nb_window_create (GtkNotebook *source,
gint y,
gpointer data)
{
- struct input_event event;
- Lisp_Object frame;
FRAME_PTR f = g_object_get_data (G_OBJECT (page), XG_FRAME_DATA);
- tabs_gc_data *oconf = g_object_get_data (G_OBJECT (page),
- XG_TAB_CONFIG_KEY);
- XSETFRAME (frame, f);
- if (!oconf) oconf = xg_store_win_config (page, f);
-
-
- EVENT_INIT (event);
- event.kind = TAB_EVENT;
- event.frame_or_window = frame;
- event.arg = Fcons (make_number (2), Qnil);
- event.x = make_number (x);
- event.y = make_number (y);
- kbd_buffer_store_event (&event);
-
- return notebook_on_hold = GTK_NOTEBOOK (gtk_notebook_new ());
+ GtkWidget *cur = f->output_data.x->current_tab;
+ char *key = g_object_get_data (G_OBJECT (cur), XG_TAB_KEY);
+
+ notebook_on_hold = GTK_NOTEBOOK (gtk_notebook_new ());
+ store_tab_event (f, Fcons (Qtab_new_frame,
+ Fcons (intern (key), Qnil)),
+ x, y);
+ return notebook_on_hold;
}
int
@@ -1294,10 +1261,7 @@ xg_set_current_tab (FRAME_PTR f, const char *key)
}
if (page >= 0 && page < pages && page != current_page)
- {
- gtk_notebook_set_current_page (wnote, page);
- xg_switch_page_cb (wnote, NULL, page, f);
- }
+ gtk_notebook_set_current_page (wnote, page);
}
@@ -1315,28 +1279,6 @@ xg_get_tab_key (FRAME_PTR f, int nr)
return (const char *)g_object_get_data (G_OBJECT (w), XG_TAB_KEY);
}
-Lisp_Object
-xg_tab_get_win_config (FRAME_PTR f, int nr)
-{
- GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
- GtkWidget *w;
- tabs_gc_data *conf;
-
- if (!wnote || nr >= gtk_notebook_get_n_pages (wnote)
- || (w = gtk_notebook_get_nth_page (wnote, nr)) == NULL)
- return Qnil;
-
- conf = g_object_get_data (G_OBJECT (w), XG_TAB_CONFIG_KEY);
- if (!conf) conf = xg_store_win_config (w, f);
- else if (w == FRAME_GTK_WIDGET (f))
- {
- Lisp_Object frame;
- XSETFRAME (frame, f);
- conf->object = Fcurrent_window_configuration (frame);
- }
- return conf ? conf->object : Qnil;
-}
-
void
xg_tabs_always_show (FRAME_PTR f, int show)
{
@@ -1354,11 +1296,15 @@ xg_setup_notebook (FRAME_PTR f, GtkWidget *wvbox, GtkWidget *wnote)
{
GtkRcStyle *style;
- gtk_box_pack_end (GTK_BOX (wvbox), wnote, TRUE, TRUE, 0);
+ gtk_box_pack_end (GTK_BOX (wvbox), wnote, FALSE, FALSE, 0);
+ gtk_box_reorder_child (GTK_BOX (wvbox), wnote, -2);
+
g_signal_connect (G_OBJECT (wnote), "switch-page",
G_CALLBACK (xg_switch_page_cb), f);
g_signal_connect (G_OBJECT (wnote), "page-added",
G_CALLBACK (xg_page_added_cb), f);
+ g_signal_connect (G_OBJECT (wnote), "page-removed",
+ G_CALLBACK (xg_page_removed_cb), f);
g_object_set (G_OBJECT (wnote), "tab-border", 0, NULL);
gtk_notebook_popup_disable (GTK_NOTEBOOK (wnote));
@@ -1389,75 +1335,29 @@ xg_enable_tabs (FRAME_PTR f, int enable)
|| (wnote != NULL && enable))
return;
- g_object_ref (G_OBJECT (wfixed));
if (enable)
{
GtkWidget *wlbl;
- char *key = g_object_get_data (G_OBJECT (wfixed), XG_TAB_KEY);
+ char *key;
wnote = gtk_notebook_new ();
+ wfixed = xg_add_fixed_for_tab (f);
+ key = g_object_get_data (G_OBJECT (wfixed), XG_TAB_KEY);
f->output_data.x->notebook_widget = wnote;
- gtk_container_remove (GTK_CONTAINER (wvbox), wfixed);
xg_setup_notebook (f, wvbox, wnote);
wlbl = xg_tab_label_widget (f, key, wfixed);
gtk_notebook_append_page (GTK_NOTEBOOK (wnote), wfixed, wlbl);
gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (wnote), wfixed, TRUE);
gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (wnote), wfixed, TRUE);
- gtk_widget_show_all (wnote);
}
else
{
xg_delete_all_tabs (f);
-
- /* Somehow scroll bars get destroyed when the notebook widget is
- destroyed even if I take a ref to them. So remove them from
- wfixed and later put them back. */
- GList *children = GTK_FIXED (wfixed)->children;
- GSList *todo = NULL, *iter;
- for ( ; children; children = g_list_next (children))
- {
- GtkFixedChild *child = (GtkFixedChild*)children->data;
- if (GTK_IS_EVENT_BOX (child->widget))
- {
- GtkFixedChild *node = xmalloc (sizeof(*node));
- *node = *child;
- todo = g_slist_prepend (todo, node);
- }
- }
-
- for (iter = todo; iter; iter = g_slist_next (iter))
- {
- GtkFixedChild *child = (GtkFixedChild*)iter->data;
- GtkWidget *wevbox = child->widget;
- g_object_ref (G_OBJECT (wevbox));
- g_object_ref (G_OBJECT (gtk_bin_get_child (GTK_BIN (wevbox))));
- gtk_container_remove (GTK_CONTAINER (wfixed), wevbox);
- }
-
gtk_container_remove (GTK_CONTAINER (wvbox), wnote);
- gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0);
f->output_data.x->notebook_widget = NULL;
-
- for (iter = todo; iter; iter = g_slist_next (iter))
- {
- GtkFixedChild *child = (GtkFixedChild*)iter->data;
- GtkWidget *wevbox = child->widget;
- gtk_fixed_put (GTK_FIXED (wfixed), wevbox, child->x, child->y);
- g_object_unref (G_OBJECT (wevbox));
- g_object_unref (G_OBJECT (gtk_bin_get_child (GTK_BIN (wevbox))));
- free (iter->data);
- }
-
- if (todo) g_slist_free (todo);
+ f->output_data.x->current_tab = NULL;
}
-
- gtk_widget_realize (wfixed);
- gtk_widget_show_all (wfixed);
- FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed);
- FRAME_GTK_WIDGET (f) = wfixed;
- g_object_unref (G_OBJECT (wfixed));
- gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
}
@@ -1475,7 +1375,6 @@ xg_create_frame_widgets (f)
GtkWidget *wnote = NULL;
char *title = 0;
GtkWidget *wfixed;
- tabs_gc_data *conf;
BLOCK_INPUT;
@@ -1518,6 +1417,7 @@ xg_create_frame_widgets (f)
FRAME_GTK_OUTER_WIDGET (f) = wtop;
f->output_data.x->vbox_widget = wvbox;
f->output_data.x->notebook_widget = wnote;
+ f->output_data.x->current_tab = NULL;
gtk_container_add (GTK_CONTAINER (wtop), wvbox);
@@ -1540,20 +1440,22 @@ xg_create_frame_widgets (f)
f->win_gravity
= gtk_window_get_gravity (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
+ wfixed = xg_add_fixed (f);
+ gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0);
+
if (wnote)
{
xg_setup_notebook (f, wvbox, wnote);
if (!notebook_on_hold)
- xg_add_tab (f, "Page 1");
-
- wfixed = gtk_notebook_get_nth_page (GTK_NOTEBOOK (wnote), 0);
- }
- else
- {
- wfixed = xg_add_fixed (f);
- gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0);
+ xg_add_tab (f, "Page_1");
+ else
+ xg_page_added_cb (GTK_NOTEBOOK (wnote),
+ gtk_notebook_get_nth_page (GTK_NOTEBOOK (wnote),
+ 0),
+ 0, f);
}
+
/* Must realize the windows so the X window gets created. It is used
@@ -1563,19 +1465,10 @@ xg_create_frame_widgets (f)
FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed);
FRAME_GTK_WIDGET (f) = wfixed;
- conf = g_object_get_data (G_OBJECT (wfixed), XG_TAB_CONFIG_KEY);
- if (conf
- && Fwindow_configuration_p (conf->object) &&
- XFRAME (Fwindow_configuration_frame (conf->object)) != f)
- {
- Lisp_Object frame;
- XSETFRAME (frame, f);
- Fchange_window_configuration_frame (conf->object, frame);
- Fset_window_configuration (conf->object);
- }
-
notebook_on_hold = NULL;
-
+ gtk_widget_show (wfixed);
+ gtk_widget_show (wvbox);
+
UNBLOCK_INPUT;
return 1;
@@ -2504,8 +2397,6 @@ xg_mark_data ()
if (! NILP (cb_data->help))
mark_object (cb_data->help);
}
- for (iter = tabs_gc_list.next; iter; iter = iter->next)
- mark_object (((tabs_gc_data *) iter)->object);
}
@@ -4535,8 +4426,8 @@ find_rtl_image (f, image, rtl)
Lisp_Object rtl_image = PROP (TOOL_BAR_ITEM_IMAGES);
if (!NILP (file = file_for_image (rtl_image)))
{
- file = call1 (intern ("file-name-sans-extension"),
- Ffile_name_nondirectory (file));
+ file = call1 (Qfile_sans_ext,
+ Ffile_name_nondirectory (file));
if (EQ (Fequal (file, rtl_name), Qt))
{
image = rtl_image;
@@ -4939,7 +4830,6 @@ xg_initialize ()
id_to_widget.max_size = id_to_widget.used = 0;
id_to_widget.widgets = 0;
xg_tab_nr = 1;
- tabs_gc_list.prev = tabs_gc_list.next = 0;
xg_always_show_tabs = 0;
/* Remove F10 as a menu accelerator, it does not mix well with Emacs key
@@ -4979,6 +4869,24 @@ xg_initialize ()
"widget \"*\" style \"noborder\"\n");
}
+void
+syms_of_gtkutil ()
+{
+ Qtab_new_frame = intern_c_string ("tab-new-frame");
+ staticpro (&Qtab_new_frame);
+ Qtab_changed = intern_c_string ("tab-changed");
+ staticpro (&Qtab_changed);
+ Qtab_added = intern_c_string ("tab-added");
+ staticpro (&Qtab_added);
+ Qtab_removed = intern_c_string ("tab-removed");
+ staticpro (&Qtab_removed);
+ Qfile_sans_ext = intern_c_string ("file-name-sans-extension");
+ staticpro (&Qfile_sans_ext);
+ Qx_gtk_map_stock = intern_c_string ("x-gtk-map-stock");
+ staticpro (&Qx_gtk_map_stock);
+}
+
+
#endif /* USE_GTK */
/* 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,
int only_dir_p));
extern char *xg_get_font_name P_ ((FRAME_PTR f, char *));
+
extern const char *xg_add_tab P_ ((FRAME_PTR f, const char *name));
extern void xg_delete_tab P_ ((FRAME_PTR f, const char *name));
extern void xg_delete_all_tabs P_ ((FRAME_PTR f));
@@ -146,8 +147,6 @@ extern int xg_current_tab P_ ((FRAME_PTR f));
extern const char *xg_get_tab_key P_ ((FRAME_PTR f, int nr));
extern void xg_set_current_tab P_ ((FRAME_PTR f, const char *key));
extern void xg_enable_tabs P_ ((FRAME_PTR f, int enable));
-
-extern Lisp_Object xg_tab_get_win_config P_ ((FRAME_PTR f, int nr));
extern void xg_tabs_always_show P_ ((FRAME_PTR f, int show));
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 *,
/* Defined in xsettings.c */
extern void syms_of_xsettings P_ ((void));
+/* Defined in gtkutil.c */
+extern void syms_of_gtkutil P_ ((void));
+
/* Defined in vm-limit.c. */
extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ()));
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,
Vwindow_list = Qnil;
#undef MAP_WINDOW
+
+ return config;
}
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,
If LABEL is nil, use current buffer name.
FRAME nil means use the selected frame.
-Returns the key for the tab, which can be passed to `tab-delete'. */)
+Returns the key for the tab ( symbol), which can be passed to `tab-delete'. */)
(label, frame)
Lisp_Object label, frame;
{
@@ -5925,7 +5925,7 @@ Returns the key for the tab, which can be passed to `tab-delete'. */)
key = xg_add_tab (f, SDATA (label));
UNBLOCK_INPUT;
- return make_string (key, strlen (key));
+ return intern (key);
}
DEFUN ("tab-delete", Ftab_delete,
@@ -5938,11 +5938,11 @@ FRAME nil means use the selected frame. */)
{
FRAME_PTR f = check_x_frame (frame);
if (f->no_tabs) return Qnil;
- if (!NILP (key) && !STRINGP (key))
- error ("Key is not string or nil");
+ if (!NILP (key) && !SYMBOLP (key))
+ error ("Key is not a symbol or nil");
BLOCK_INPUT;
- xg_delete_tab (f, NILP (key) ? NULL : SDATA (key));
+ xg_delete_tab (f, NILP (key) ? NULL : SDATA (SYMBOL_NAME (key)));
UNBLOCK_INPUT;
return Qnil;
@@ -6056,9 +6056,7 @@ DEFUN ("tab-configuration", Ftab_configuration,
Stab_configuration, 0, 1, 0,
doc: /* Return the tab configuration on FRAME.
FRAME nil means use the selected frame.
-Returns an alist where each element is of type (KEY WINDOWCONFIG).
-KEY is the name of the tab as returned by `tab_new´.
-WINDOWCONFIG is the window configuration for the tab.
+Returns an list where each element is a symbol representing a tab.
If FRAME is a tab-less frame, returns nil. */)
(frame)
@@ -6072,12 +6070,10 @@ If FRAME is a tab-less frame, returns nil. */)
nr = xg_tab_count (f);
for (i = 0; i < nr; ++i)
{
- Lisp_Object wc = xg_tab_get_win_config (f, i);
const char *key = xg_get_tab_key (f, i);
- cc = Fcons (Fcons (key ? make_string (key, strlen (key)) : Qnil,
- NILP (wc) ? wc : Fcons (wc, Qnil)),
- cc);
+ if (key)
+ cc = Fcons (intern (key), cc);
}
return cc;
@@ -6098,7 +6094,7 @@ If FRAME is a tab-less frame, returns nil. */)
if (f->no_tabs) return Qnil;
nr = xg_current_tab (f);
const char *key = xg_get_tab_key (f, nr);
- return key ? make_string (key, strlen (key)) : Qnil;
+ return key ? intern (key) : Qnil;
}
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. */)
{
FRAME_PTR f = check_x_frame (frame);
if (f->no_tabs) return Qnil;
- CHECK_STRING (key);
+ CHECK_SYMBOL (key);
BLOCK_INPUT;
- xg_set_current_tab (f, SDATA (key));
+ xg_set_current_tab (f, SDATA (SYMBOL_NAME (key)));
UNBLOCK_INPUT;
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;
#ifdef USE_GTK
/* The name of the Emacs icon file. */
static Lisp_Object xg_default_icon_file;
-
-/* Used in gtkutil.c. */
-Lisp_Object Qx_gtk_map_stock;
#endif
/* Used in x_flush. */
@@ -9265,7 +9262,7 @@ x_make_frame_visible (f)
}
#else /* not USE_X_TOOLKIT */
#ifdef USE_GTK
- gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
+ gtk_widget_show (FRAME_GTK_OUTER_WIDGET (f));
gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
#else
if (FRAME_X_EMBEDDED_P (f))
@@ -10970,9 +10967,6 @@ syms_of_xterm ()
#ifdef USE_GTK
xg_default_icon_file = make_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
staticpro (&xg_default_icon_file);
-
- Qx_gtk_map_stock = intern_c_string ("x-gtk-map-stock");
- staticpro (&Qx_gtk_map_stock);
#endif
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
GtkWidget *vbox_widget;
/* The notebook (i.e. tab) widget. */
GtkWidget *notebook_widget;
+ /* The current note book child. */
+ GtkWidget *current_tab;
/* The menubar in this frame. */
GtkWidget *menubar_widget;
/* The tool bar in this frame */