]> git.eshelyaron.com Git - emacs.git/commitdiff
Tab keys are symbols. gtk-tabs
authorJan D <jan.h.d@swipnet.se>
Sun, 16 May 2010 18:49:26 +0000 (20:49 +0200)
committerJan D <jan.h.d@swipnet.se>
Sun, 16 May 2010 18:49:26 +0000 (20:49 +0200)
Tab switch is in elisp.
Save/restore point in tabs also.

lisp/native-tabs.el
src/emacs.c
src/gtkutil.c
src/gtkutil.h
src/lisp.h
src/window.c
src/xfns.c
src/xterm.c
src/xterm.h

index afd46a9124b939435c39a7792c31f27dfa4411ac..283c7a640dd3dfd365c47759185a524b92bb04d8 100644 (file)
@@ -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)
index 400a6b0e5947eb864e49ca88729abf512ea1141e..72680e37615518ec5a6c51d01e17fe8f88de318d 100644 (file)
@@ -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
index 491b1a1c01417909db32e671d8d7378c54088125..fbe744b5124d838b69b910f059104d85af13d425 100644 (file)
@@ -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;
+
 \f
 /***********************************************************************
                       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
index b005498e84310b639a6e558c8a6e21cfe943755f..a08d387809bb674b5e6dee1297662894500b4f9a 100644 (file)
@@ -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));
 
 
index 7f5d5df66c61106d5caf3223a929aa077ce4a2d7..b7920a74c761f75a5e282817696035b718329782 100644 (file)
@@ -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) ()));
 
index 4874b1c7ff61a2355c5b5ac1121c43b6cf862208..89f5e312ccb4cd905728e27c33affc78922b3572 100644 (file)
@@ -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,
index b192263e87be2362ecb39caa0dd5d126041c63a7..3b40f767544ac02a8ab7b104dc7ebcad2d4d49b0 100644 (file)
@@ -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;
index 54cac40e091c6180c338bb605993f0b8ea33fbb2..91a65fc32cb7e8c125d1c70f761ed11e1e13c0d7 100644 (file)
@@ -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",
index 09be1626c19728fa0aa9ad253e1c57d2d2dcfaf7..1925210b623fbd7347e68144b29465f70697768b 100644 (file)
@@ -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  */