to switch to a tab showing buffer.
Focus border around tabs removed.
norecord)
(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.
+FRAME nil means selected frame.
+
+Returns the key for the tab switch to, or nil if no tab displays
+BUFFER-OR-NAME."
+ (let* ((buffer (if (bufferp buffer-or-name)
+ buffer-or-name
+ (get-buffer buffer-or-name)))
+ (tabs (if buffer (tab-configuration frame) nil))
+ (tab-key))
+ (while (and tabs (null tab-key))
+ (let* ((elt (car tabs))
+ (winconf (cadr elt))
+ (buffers (buffers-in-window-configuration winconf)))
+ (if (memq buffer buffers)
+ (setq tab-key (car 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)))
+
+(defun switch-to-buffer-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)))
+
(defun handle-tab-event (event)
"Handle tab-event to change tabs on the frame in EVENT."
(interactive "e")
(global-set-key "\C-x70" 'tab-delete)
(global-set-key "\C-x71" 'tab-delete-other)
(global-set-key "\C-x72" 'tab-new)
+ (global-set-key "\C-x73" 'switch-to-buffer-tab)
(global-set-key "\C-x7b" 'switch-to-buffer-other-tab)
(global-set-key "\C-x7f" 'find-file-new-tab)
(global-set-key "\C-x7o" 'tab-next)
} 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)
+{
+ 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;
+}
+
static void
xg_check_show_tabs (FRAME_PTR f,
GtkNotebook *wnote)
tabs_gc_data *oconf = g_object_get_data (G_OBJECT (old),
XG_TAB_CONFIG_KEY);
if (!oconf)
- {
- oconf = xmalloc (sizeof(*oconf));
- g_object_set_data (G_OBJECT (old), XG_TAB_CONFIG_KEY, oconf);
- xg_list_insert (&tabs_gc_list, &oconf->ptrs);
- }
+ oconf = xg_store_win_config (old, f);
XSETFRAME (frame, f);
- oconf->object = Fcurrent_window_configuration (frame);
EVENT_INIT (event);
event.kind = TAB_EVENT;
tabs_gc_data *oconf = g_object_get_data (G_OBJECT (page),
XG_TAB_CONFIG_KEY);
XSETFRAME (frame, f);
- if (!oconf)
- {
- oconf = xmalloc (sizeof(*oconf));
- g_object_set_data (G_OBJECT (page), XG_TAB_CONFIG_KEY, oconf);
- xg_list_insert (&tabs_gc_list, &oconf->ptrs);
- oconf->object = Fcurrent_window_configuration (frame);
- }
+ if (!oconf) oconf = xg_store_win_config (page, f);
+
EVENT_INIT (event);
event.kind = TAB_EVENT;
return notebook_on_hold = GTK_NOTEBOOK (gtk_notebook_new ());
}
+int
+xg_tab_count (FRAME_PTR f)
+{
+ GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
+ return wnote ? gtk_notebook_get_n_pages (wnote) : 1;
+}
+
+int
+xg_current_tab (FRAME_PTR f)
+{
+ GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
+ return wnote ? gtk_notebook_get_current_page (wnote) : 0;
+}
+
+void
+xg_set_current_tab (FRAME_PTR f, const char *key)
+{
+ GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
+ int i, pages = gtk_notebook_get_n_pages (wnote);
+ int page = -1;
+ int current_page = gtk_notebook_get_current_page (wnote);
+ if (pages == 1 || !key) return;
+
+ for (i = 0; i < pages; ++i)
+ {
+ GtkWidget *w = gtk_notebook_get_nth_page (wnote, i);
+ char *k;
+ if (!w) continue;
+ k = g_object_get_data (G_OBJECT (w), XG_TAB_KEY);
+ if (k && strcmp (k, key) == 0)
+ {
+ page = i;
+ break;
+ }
+ }
+
+ if (page >= 0 && page < pages && page != current_page)
+ {
+ gtk_notebook_set_current_page (wnote, page);
+ xg_switch_page_cb (wnote, NULL, page, f);
+ }
+}
+
+
+
+const char *
+xg_get_tab_key (FRAME_PTR f, int nr)
+{
+ GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
+ GtkWidget *w;
+
+ if (!wnote || nr >= gtk_notebook_get_n_pages (wnote)
+ || (w = gtk_notebook_get_nth_page (wnote, nr)) == NULL)
+ return NULL;
+
+ 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;
+}
+
+
+
/* Create and set up the GTK widgets for frame F.
Return 0 if creation failed, non-zero otherwise. */
extern void xg_set_tab_label P_ ((FRAME_PTR f, const char *label));
extern void xg_tab_next P_ ((FRAME_PTR f));
extern void xg_tab_previous P_ ((FRAME_PTR f));
+extern int xg_tab_count P_ ((FRAME_PTR f));
+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 Lisp_Object xg_tab_get_win_config P_ ((FRAME_PTR f, int nr));
extern GtkWidget *xg_create_widget P_ ((char *type,
char *name,
#undef MAP_WINDOW
}
+DEFUN ("buffers-in-window-configuration", Fbuffers_in_window_configuration,
+ Sbuffers_in_window_configuration, 1, 1, 0,
+ doc: /* Return a list of buffers that CONFIGURATION is showing.
+CONFIGURATION must be a value previously returned
+by `current-window-configuration' (which see). */)
+ (configuration)
+ Lisp_Object configuration;
+{
+ struct save_window_data *data;
+ struct Lisp_Vector *saved_windows;
+ int k;
+ struct saved_window *p;
+ Lisp_Object buffers = Qnil, tail;
+
+ CHECK_WINDOW_CONFIGURATION (configuration);
+
+ data = (struct save_window_data *) XVECTOR (configuration);
+ saved_windows = XVECTOR (data->saved_windows);
+ for (k = 0; k < saved_windows->size; k++)
+ {
+ p = SAVED_WINDOW_N (saved_windows, k);
+ if (!NILP (p->buffer))
+ {
+ if (NILP (buffers))
+ tail = buffers = Fcons (p->buffer, Qnil);
+ else
+ {
+ XSETCDR (tail, Fcons (p->buffer, Qnil));
+ tail = XCDR (tail);
+ }
+ }
+ }
+
+ return buffers;
+}
+
DEFUN ("set-window-configuration", Fset_window_configuration,
Sset_window_configuration, 1, 1, 0,
doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
defsubr (&Swindow_configuration_p);
defsubr (&Swindow_configuration_frame);
defsubr (&Schange_window_configuration_frame);
+ defsubr (&Sbuffers_in_window_configuration);
defsubr (&Sset_window_configuration);
defsubr (&Scurrent_window_configuration);
defsubr (&Ssave_window_excursion);
return Qnil;
}
+DEFUN ("tab-nr-of-tabs", Ftab_nr_of_tabs,
+ Stab_nr_of_tabs, 0, 1, 0,
+ doc: /* Return the number of tabs on FRAME.
+FRAME nil means use the selected frame. */)
+ (frame)
+ Lisp_Object frame;
+{
+ FRAME_PTR f = check_x_frame (frame);
+ int nr = 1;
+ Lisp_Object o;
+
+
+ if (!f->no_tabs)
+ nr = xg_tab_count (f);
+
+ XSETFASTINT (o, nr);
+ return o;
+}
+
+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.
+
+If FRAME is a tab-less frame, returns nil. */)
+ (frame)
+ Lisp_Object frame;
+{
+ FRAME_PTR f = check_x_frame (frame);
+ int nr, i;
+ Lisp_Object cc = Qnil;
+
+ if (f->no_tabs) return Qnil;
+ 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);
+ }
+
+ return cc;
+}
+
+DEFUN ("tab-current", Ftab_current,
+ Stab_current, 0, 1, 0,
+ doc: /* Return the key for the current tab on FRAME.
+FRAME nil means use the selected frame.
+If FRAME is a tab-less frame, returns nil. */)
+ (frame)
+ Lisp_Object frame;
+{
+ FRAME_PTR f = check_x_frame (frame);
+ Lisp_Object cc = Qnil;
+ int nr;
+
+ 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;
+}
+
+DEFUN ("tab-show", Ftab_show,
+ Stab_show, 0, 2, 0,
+ doc: /* Make tab with key the current tab on FRAME.
+FRAME nil means use the selected frame.
+If FRAME is a tab-less frame or the key doesn't refer to a tab, do nothing. */)
+ (key, frame)
+ Lisp_Object key, frame;
+{
+ FRAME_PTR f = check_x_frame (frame);
+ if (f->no_tabs) return Qnil;
+ CHECK_STRING (key);
+
+ BLOCK_INPUT;
+ xg_set_current_tab (f, SDATA (key));
+ UNBLOCK_INPUT;
+
+ return Qnil;
+}
+
#endif
void
defsubr (&Stab_next);
defsubr (&Stab_previous);
defsubr (&Stab_set_label);
+ defsubr (&Stab_nr_of_tabs);
+ defsubr (&Stab_configuration);
+ defsubr (&Stab_current);
+ defsubr (&Stab_show);
#endif /* USE_GTK */