]> git.eshelyaron.com Git - emacs.git/commitdiff
Support setting disable-tabs ar runtime. tab-enable is new.
authorJan Djärv <jan.h.d@swipnet.se>
Sat, 10 Apr 2010 10:15:09 +0000 (12:15 +0200)
committerJan Djärv <jan.h.d@swipnet.se>
Sat, 10 Apr 2010 10:15:09 +0000 (12:15 +0200)
src/frame.c
src/frame.h
src/gtkutil.c
src/gtkutil.h
src/xfns.c

index d7376a476bcdd8b0ab7a125373e6277a4d41e646..56dcad332e16d70b00850b96f391937758b9d149 100644 (file)
@@ -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.  */
 
index e83f995d186bbd33d85ee4569962bd9f2e65c057..95941cb4e3897b6c7793e465804c5c86aeb90137 100644 (file)
@@ -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,
index 2757a8acf3debfe3c38c7141f670f8384ca2fdce..87e0883fe3458a153d384a0d71edab3d263d8aed 100644 (file)
@@ -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");
index 087f7d6df55d6180fcd1d77cee0384658394958a..07a886e8e90125bd0538980df7e35a8c20e63c71 100644 (file)
@@ -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));
 
index 09f333ba400cfc92aeb35a9b5105fbb29602e549..c08fad851d43a810f28073ba27951555278ac829 100644 (file)
@@ -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 */