From: Jan Djärv Date: Sat, 10 Apr 2010 10:15:09 +0000 (+0200) Subject: Support setting disable-tabs ar runtime. tab-enable is new. X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2163ae3a765fd2438b2e40fe461b284d3f65ca47;p=emacs.git Support setting disable-tabs ar runtime. tab-enable is new. --- diff --git a/src/frame.c b/src/frame.c index d7376a476bc..56dcad332e1 100644 --- a/src/frame.c +++ b/src/frame.c @@ -3324,18 +3324,6 @@ x_set_line_spacing (f, new_value, old_value) redraw_frame (f); } -void -x_set_notabs (f, new_value, old_value) - struct frame *f; - Lisp_Object new_value, old_value; -{ - Lisp_Object frame; - - /* Only allow false => true at startup. */ - if (NILP (old_value) && !NILP (new_value)) - f->no_tabs = 1; -} - /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is the previous value of that parameter, NEW_VALUE is the new value. */ diff --git a/src/frame.h b/src/frame.h index e83f995d186..95941cb4e38 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1120,7 +1120,6 @@ extern void x_set_visibility P_ ((struct frame *, Lisp_Object, Lisp_Object)); extern void x_set_autoraise P_ ((struct frame *, Lisp_Object, Lisp_Object)); extern void x_set_autolower P_ ((struct frame *, Lisp_Object, Lisp_Object)); extern void x_set_unsplittable P_ ((struct frame *, Lisp_Object, Lisp_Object)); -extern void x_set_notabs P_ ((struct frame *, Lisp_Object, Lisp_Object)); extern void x_set_vertical_scroll_bars P_ ((struct frame *, Lisp_Object, Lisp_Object)); extern void x_set_scroll_bar_width P_ ((struct frame *, Lisp_Object, diff --git a/src/gtkutil.c b/src/gtkutil.c index 2757a8acf3d..87e0883fe34 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -969,6 +969,7 @@ xg_tab_label_widget (FRAME_PTR f, GtkWidget *wbutt = gtk_button_new (); GtkWidget *wbox = gtk_hbox_new (FALSE, 0); GtkRcStyle *style; + char buf[64]; gtk_container_set_border_width (GTK_CONTAINER (wbutt), 0); gtk_container_set_border_width (GTK_CONTAINER (wbox), 0); @@ -1002,6 +1003,8 @@ 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); @@ -1040,6 +1043,16 @@ 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++); + 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); + + return wfixed; } @@ -1052,20 +1065,12 @@ xg_add_tab (FRAME_PTR f, { GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget); GtkWidget *wfixed = xg_add_fixed (f); - char buf[64]; - char *key = NULL; + char *key = g_object_get_data (G_OBJECT (wfixed), XG_TAB_KEY); int n; GtkWidget *wlbl = xg_tab_label_widget (f, name, wfixed); BLOCK_INPUT; - 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); - n = gtk_notebook_append_page (wnote, wfixed, wlbl); gtk_notebook_set_tab_reorderable (wnote, wfixed, TRUE); gtk_notebook_set_tab_detachable (wnote, wfixed, TRUE); @@ -1329,6 +1334,118 @@ xg_tab_get_win_config (FRAME_PTR f, int nr) return conf ? conf->object : Qnil; } +static void +xg_setup_notebook (FRAME_PTR f, GtkWidget *wvbox, GtkWidget *wnote) +{ + GtkRcStyle *style; + + gtk_box_pack_end (GTK_BOX (wvbox), wnote, TRUE, TRUE, 0); + 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_object_set (G_OBJECT (wnote), "tab-border", 0, NULL); + gtk_notebook_popup_disable (GTK_NOTEBOOK (wnote)); + gtk_notebook_set_scrollable (GTK_NOTEBOOK (wnote), TRUE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (wnote), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (wnote), 0); +#if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION >= 12 + gtk_notebook_set_group (GTK_NOTEBOOK (wnote), (gpointer)1); +#else + gtk_notebook_set_group_id (GTK_NOTEBOOK (wnote), 1); +#endif + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (wnote), FALSE); + + style = gtk_widget_get_modifier_style (wnote); + style->xthickness = style->ythickness = 0; + gtk_widget_modify_style (wnote, style); +} + +void +xg_enable_tabs (FRAME_PTR f, int enable) +{ + GtkWidget *wnote = f->output_data.x->notebook_widget; + struct x_output *x = f->output_data.x; + GtkWidget *wvbox = x->vbox_widget; + GtkWidget *wfixed = FRAME_GTK_WIDGET (f); + + if ((wnote == NULL && !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); + + wnote = gtk_notebook_new (); + 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); + } + + 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)); +} + + /* Create and set up the GTK widgets for frame F. @@ -1410,27 +1527,7 @@ xg_create_frame_widgets (f) if (wnote) { - gtk_box_pack_end (GTK_BOX (wvbox), wnote, TRUE, TRUE, 0); - 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_object_set (G_OBJECT (wnote), "tab-border", 0, NULL); - gtk_notebook_popup_disable (GTK_NOTEBOOK (wnote)); - gtk_notebook_set_scrollable (GTK_NOTEBOOK (wnote), TRUE); - gtk_notebook_set_show_border (GTK_NOTEBOOK (wnote), FALSE); - gtk_container_set_border_width (GTK_CONTAINER (wnote), 0); -#if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION >= 12 - gtk_notebook_set_group (GTK_NOTEBOOK (wnote), (gpointer)1); -#else - gtk_notebook_set_group_id (GTK_NOTEBOOK (wnote), 1); -#endif - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (wnote), FALSE); - - GtkRcStyle *style = gtk_widget_get_modifier_style (wnote); - style->xthickness = style->ythickness = 0; - gtk_widget_modify_style (wnote, style); + xg_setup_notebook (f, wvbox, wnote); if (!notebook_on_hold) xg_add_tab (f, "Page 1"); diff --git a/src/gtkutil.h b/src/gtkutil.h index 087f7d6df55..07a886e8e90 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h @@ -145,6 +145,7 @@ 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 void xg_enable_tabs P_ ((FRAME_PTR f, int enable)); extern Lisp_Object xg_tab_get_win_config P_ ((FRAME_PTR f, int nr)); diff --git a/src/xfns.c b/src/xfns.c index 09f333ba400..c08fad851d4 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -505,6 +505,7 @@ static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object)); void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object)); +static void x_set_notabs P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); @@ -740,6 +741,22 @@ x_set_wait_for_wm (f, new_value, old_value) f->output_data.x->wait_for_wm = !NILP (new_value); } +static void +x_set_notabs (f, new_value, old_value) + struct frame *f; + Lisp_Object new_value, old_value; +{ + if (! EQ (new_value, old_value)) + { + f->no_tabs = !NILP (new_value); +#ifdef USE_GTK + BLOCK_INPUT; + xg_enable_tabs (f, NILP (new_value)); + UNBLOCK_INPUT; +#endif + } +} + #ifdef USE_GTK /* Set icon from FILE for frame F. By using GTK functions the icon @@ -5869,7 +5886,8 @@ Returns the key for the tab, which can be passed to `tab-delete'. */) FRAME_PTR f = check_x_frame (frame); const char *key; - if (f->no_tabs) return Qnil; + if (f->no_tabs) error ("Frame is a tabless frame"); + if (NILP (label)) { if (!NILP (Fminibufferp (Qnil))) return; @@ -6060,7 +6078,7 @@ If FRAME is a tab-less frame, returns nil. */) } DEFUN ("tab-show", Ftab_show, - Stab_show, 0, 2, 0, + Stab_show, 1, 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. */) @@ -6078,6 +6096,19 @@ If FRAME is a tab-less frame or the key doesn't refer to a tab, do nothing. */) return Qnil; } +DEFUN ("tab-enable", Ftab_enable, + Stab_enable, 1, 2, 0, + doc: /* Enable or disable tabs on FRAME. +FRAME nil means use the selected frame. +If enable is non-nil, enable tabs. If it is nil, disable tabs. */) + (enable, frame) + Lisp_Object enable, frame; +{ + FRAME_PTR f = check_x_frame (frame); + x_set_notabs (f, NILP (enable) ? Qt : Qnil, f->no_tabs ? Qt : Qnil); + return Qnil; +} + #endif void @@ -6249,6 +6280,7 @@ the tool bar buttons. */); defsubr (&Stab_configuration); defsubr (&Stab_current); defsubr (&Stab_show); + defsubr (&Stab_enable); #endif /* USE_GTK */