From: Jan Djärv Date: Mon, 22 Mar 2010 12:22:43 +0000 (+0100) Subject: Native Gtk+ tabs, first try. X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=3c579bff2bb7ce9d6ec2df407f038b31526c63f4;p=emacs.git Native Gtk+ tabs, first try. --- diff --git a/lisp/loadup.el b/lisp/loadup.el index 85222ce7d9e..0cf3a4c2088 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -202,6 +202,9 @@ (if (or (featurep 'system-font-setting) (featurep 'font-render-setting)) (load "font-setting")) +(if (featurep 'tabs) + (load "native-tabs")) + (if (featurep 'x) (progn (load "x-dnd") diff --git a/src/gtkutil.c b/src/gtkutil.c index 2764382e8a1..2254978a79e 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -753,6 +753,274 @@ xg_pix_to_gcolor (w, pixel, c) gdk_colormap_query_color (map, pixel, c); } +/*********************************************************************** + Tab functions + ***********************************************************************/ +#define XG_TAB_KEY "emacs-tab-key" +static int xg_tab_nr; + +/* Callback called when the current tab changes. */ + +static void +xg_switch_page_cb (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num, + gpointer user_data) +{ + BLOCK_INPUT; + GtkWidget *w = gtk_notebook_get_nth_page (notebook, page_num); + FRAME_PTR f = (FRAME_PTR) user_data; + if (w != FRAME_GTK_WIDGET (f)) + { + GtkWidget *old = FRAME_GTK_WIDGET (f); + GList *children = old ? GTK_FIXED (old)->children : NULL; + GSList *todo = NULL, *iter; + struct input_event event; + Lisp_Object frame; + char *key = g_object_get_data (G_OBJECT (w), XG_TAB_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 = iter->next) + { + 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) + { + char *oldkey = g_object_get_data (G_OBJECT (old), XG_TAB_KEY); + XSETFRAME (frame, f); + EVENT_INIT (event); + event.kind = TAB_CHANGED_EVENT; + event.frame_or_window = frame; + event.arg = Fcons (make_string (key, strlen (key)), + make_string (oldkey, strlen (oldkey))); + kbd_buffer_store_event (&event); + } + } + + UNBLOCK_INPUT; +} + +static void +xg_fixed_destroy_cb (GtkWidget *widget, + gpointer client_data) +{ + char *key = g_object_get_data (G_OBJECT (widget), XG_TAB_KEY); + xfree (key); +} + +/* Add a new tab and make it current. + Returns a unique identifier for this tab. */ + +const char * +xg_add_tab (FRAME_PTR f, + const char *name) +{ + GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget); + GtkWidget *wfixed = gtk_fixed_new (); + GdkColor bg; + GtkRcStyle *style; + char buf[64]; + char *key; + int n; + + gtk_widget_set_name (wfixed, SSDATA (Vx_resource_name)); + sprintf (buf, "Page %d", xg_tab_nr++); + key = xstrdup (buf); + g_object_set_data (G_OBJECT (wfixed), XG_TAB_KEY, key); + + gtk_fixed_set_has_window (GTK_FIXED (wfixed), TRUE); + /* We don't want this widget double buffered, because we draw on it + with regular X drawing primitives, so from a GTK/GDK point of + view, the widget is totally blank. When an expose comes, this + will make the widget blank, and then Emacs redraws it. This flickers + a lot, so we turn off double buffering. */ + gtk_widget_set_double_buffered (wfixed, FALSE); + gtk_widget_add_events (wfixed, + GDK_POINTER_MOTION_MASK + | GDK_EXPOSURE_MASK + | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_KEY_PRESS_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK + | GDK_FOCUS_CHANGE_MASK + | GDK_STRUCTURE_MASK + | GDK_VISIBILITY_NOTIFY_MASK); + + + /* Since GTK clears its window by filling with the background color, + we must keep X and GTK background in sync. */ + xg_pix_to_gcolor (wfixed, FRAME_BACKGROUND_PIXEL (f), &bg); + gtk_widget_modify_bg (wfixed, GTK_STATE_NORMAL, &bg); + + /* Also, do not let any background pixmap to be set, this looks very + bad as Emacs overwrites the background pixmap with its own idea + of background color. */ + style = gtk_widget_get_modifier_style (wfixed); + + /* Must use g_strdup because gtk_widget_modify_style does g_free. */ + style->bg_pixmap_name[GTK_STATE_NORMAL] = g_strdup (""); + gtk_widget_modify_style (wfixed, style); + gtk_widget_show (wfixed); + n = gtk_notebook_append_page_menu (wnote, + wfixed, + name ? gtk_label_new (name) : NULL, + NULL); + gtk_notebook_set_tab_reorderable (wnote, wfixed, TRUE); + + if (n > 0) + { + gtk_notebook_set_current_page (wnote, n); + xg_switch_page_cb (wnote, NULL, n, f); + } + + g_signal_connect (G_OBJECT (wfixed), + "destroy", + G_CALLBACK (xg_fixed_destroy_cb), 0); + + return key; +} + +/* Delete a tab by its unique identifier KEY. + If no KEY is given, delete the current tab. */ + +void +xg_delete_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_to_remove = -1; + int current_page = gtk_notebook_get_current_page (wnote); + if (pages == 1) return; + + if (!key) + { + page_to_remove = current_page; + } + else + { + 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_to_remove = i; + break; + } + } + } + + if (page_to_remove >= 0 && page_to_remove < pages) + { + if (page_to_remove == current_page) + { + 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); + } +} + +/* Delete all tabs except the current tab. */ + +void +xg_delete_all_tabs (FRAME_PTR f) +{ + GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget); + int i, pages = gtk_notebook_get_n_pages (wnote); + int current_page = gtk_notebook_get_current_page (wnote); + if (pages == 1) return; + + /* First delete tabs after current_page, so current_page becomes last. */ + for (i = current_page+1; i < pages; ++i) + gtk_notebook_remove_page (wnote, i); + + /* Then delete the rest. */ + for (i = 0; i < current_page; ++i) + gtk_notebook_remove_page (wnote, 0); +} + +/* Make the next tab current. If there are no next tabs, wrap around to 0. */ + +void +xg_tab_next (FRAME_PTR f) +{ + GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget); + int current_page = gtk_notebook_get_current_page (wnote); + int pages = gtk_notebook_get_n_pages (wnote); + int switch_to; + + if (pages == 1) return; + if (current_page == pages-1) + switch_to = 0; + else + switch_to = current_page+1; + gtk_notebook_set_current_page (wnote, switch_to); + +} + +/* Make the previous tab current. If current is first, wrap around to last. */ + +void +xg_tab_previous (FRAME_PTR f) +{ + GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget); + int current_page = gtk_notebook_get_current_page (wnote); + int pages = gtk_notebook_get_n_pages (wnote); + int switch_to; + + if (pages == 1) return; + if (current_page == 0) + switch_to = pages-1; + else + switch_to = current_page-1; + gtk_notebook_set_current_page (wnote, switch_to); +} + + +void +xg_set_tab_label (FRAME_PTR f, + const char *label) +{ + GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget); + int current_page = gtk_notebook_get_current_page (wnote); + GtkWidget *w = gtk_notebook_get_nth_page (wnote, current_page); + const char *txt = gtk_notebook_get_tab_label_text (wnote, w); + if (txt == NULL || strcmp (txt, label) != 0) + gtk_notebook_set_tab_label_text (wnote, w, label); +} + /* Create and set up the GTK widgets for frame F. Return 0 if creation failed, non-zero otherwise. */ @@ -762,9 +1030,7 @@ xg_create_frame_widgets (f) { GtkWidget *wtop; GtkWidget *wvbox; - GtkWidget *wfixed; - GdkColor bg; - GtkRcStyle *style; + GtkWidget *wnote; char *title = 0; BLOCK_INPUT; @@ -777,13 +1043,13 @@ xg_create_frame_widgets (f) xg_set_screen (wtop, f); wvbox = gtk_vbox_new (FALSE, 0); - wfixed = gtk_fixed_new (); /* Must have this to place scroll bars */ + wnote = gtk_notebook_new (); - if (! wtop || ! wvbox || ! wfixed) + if (! wtop || ! wvbox || ! wnote) { if (wtop) gtk_widget_destroy (wtop); if (wvbox) gtk_widget_destroy (wvbox); - if (wfixed) gtk_widget_destroy (wfixed); + if (wnote) gtk_widget_destroy (wnote); UNBLOCK_INPUT; return 0; @@ -792,7 +1058,6 @@ xg_create_frame_widgets (f) /* Use same names as the Xt port does. I.e. Emacs.pane.emacs by default */ gtk_widget_set_name (wtop, EMACS_CLASS); gtk_widget_set_name (wvbox, "pane"); - gtk_widget_set_name (wfixed, SSDATA (Vx_resource_name)); /* If this frame has a title or name, set it in the title bar. */ if (! NILP (f->title)) title = SSDATA (ENCODE_UTF_8 (f->title)); @@ -801,24 +1066,17 @@ xg_create_frame_widgets (f) if (title) gtk_window_set_title (GTK_WINDOW (wtop), title); FRAME_GTK_OUTER_WIDGET (f) = wtop; - FRAME_GTK_WIDGET (f) = wfixed; f->output_data.x->vbox_widget = wvbox; - - gtk_fixed_set_has_window (GTK_FIXED (wfixed), TRUE); + f->output_data.x->notebook_widget = wnote; gtk_container_add (GTK_CONTAINER (wtop), wvbox); - gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0); - + 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); + if (FRAME_EXTERNAL_TOOL_BAR (f)) update_frame_tool_bar (f); - /* We don't want this widget double buffered, because we draw on it - with regular X drawing primitives, so from a GTK/GDK point of - view, the widget is totally blank. When an expose comes, this - will make the widget blank, and then Emacs redraws it. This flickers - a lot, so we turn off double buffering. */ - gtk_widget_set_double_buffered (wfixed, FALSE); - gtk_window_set_wmclass (GTK_WINDOW (wtop), SSDATA (Vx_resource_name), SSDATA (Vx_resource_class)); @@ -834,44 +1092,17 @@ xg_create_frame_widgets (f) xg_set_geometry (f); f->win_gravity = gtk_window_get_gravity (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); - - gtk_widget_add_events (wfixed, - GDK_POINTER_MOTION_MASK - | GDK_EXPOSURE_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_KEY_PRESS_MASK - | GDK_ENTER_NOTIFY_MASK - | GDK_LEAVE_NOTIFY_MASK - | GDK_FOCUS_CHANGE_MASK - | GDK_STRUCTURE_MASK - | GDK_VISIBILITY_NOTIFY_MASK); + xg_add_tab (f, NULL); + gtk_notebook_popup_enable (GTK_NOTEBOOK (wnote)); + gtk_notebook_set_scrollable (GTK_NOTEBOOK (wnote), TRUE); + GtkWidget *wfixed = gtk_notebook_get_nth_page (GTK_NOTEBOOK (wnote), 0); /* Must realize the windows so the X window gets created. It is used by callers of this function. */ gtk_widget_realize (wfixed); - FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed); - - /* Since GTK clears its window by filling with the background color, - we must keep X and GTK background in sync. */ - xg_pix_to_gcolor (wfixed, FRAME_BACKGROUND_PIXEL (f), &bg); - gtk_widget_modify_bg (wfixed, GTK_STATE_NORMAL, &bg); - - /* Also, do not let any background pixmap to be set, this looks very - bad as Emacs overwrites the background pixmap with its own idea - of background color. */ - style = gtk_widget_get_modifier_style (wfixed); - - /* Must use g_strdup because gtk_widget_modify_style does g_free. */ - style->bg_pixmap_name[GTK_STATE_NORMAL] = g_strdup (""); - gtk_widget_modify_style (wfixed, style); - - /* GTK does not set any border, and they look bad with GTK. */ - /* That they look bad is no excuse for imposing this here. --Stef - It should be done by providing the proper default in Fx_create_Frame. - f->border_width = 0; - f->internal_border_width = 0; */ + FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed); + FRAME_GTK_WIDGET (f) = wfixed; UNBLOCK_INPUT; return 1; @@ -4230,6 +4461,7 @@ xg_initialize () id_to_widget.max_size = id_to_widget.used = 0; id_to_widget.widgets = 0; + xg_tab_nr = 1; /* Remove F10 as a menu accelerator, it does not mix well with Emacs key bindings. It doesn't seem to be any way to remove properties, diff --git a/src/gtkutil.h b/src/gtkutil.h index 602228f97be..194f2df9eef 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h @@ -135,6 +135,12 @@ 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)); +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 GtkWidget *xg_create_widget P_ ((char *type, char *name, diff --git a/src/keyboard.c b/src/keyboard.c index 48d39235e3f..471ac9a4263 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -490,6 +490,7 @@ Lisp_Object Qsave_session; Lisp_Object Qdbus_event; #endif Lisp_Object Qconfig_changed_event; +Lisp_Object Qtab_changed_event; /* Lisp_Object Qmouse_movement; - also an event header */ @@ -4317,6 +4318,11 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time) obj = make_lispy_event (event); kbd_fetch_ptr = event + 1; } + else if (event->kind == TAB_CHANGED_EVENT) + { + obj = make_lispy_event (event); + kbd_fetch_ptr = event + 1; + } else { /* If this event is on a different frame, return a switch-frame this @@ -6234,6 +6240,12 @@ make_lispy_event (event) return Fcons (Qconfig_changed_event, Fcons (event->arg, Fcons (event->frame_or_window, Qnil))); + + case TAB_CHANGED_EVENT: + return Fcons (Qtab_changed_event, + Fcons (event->arg, + Fcons (event->frame_or_window, Qnil))); + #ifdef HAVE_GPM case GPM_CLICK_EVENT: { @@ -11852,6 +11864,8 @@ syms_of_keyboard () Qconfig_changed_event = intern_c_string ("config-changed-event"); staticpro (&Qconfig_changed_event); + Qtab_changed_event = intern_c_string ("tab-changed-event"); + staticpro (&Qtab_changed_event); Qmenu_enable = intern_c_string ("menu-enable"); staticpro (&Qmenu_enable); @@ -12598,6 +12612,8 @@ keys_of_keyboard () initial_define_lispy_key (Vspecial_event_map, "config-changed-event", "ignore"); + initial_define_lispy_key (Vspecial_event_map, "tab-changed-event", + "ignore"); } /* Mark the pointers in the kboard objects. diff --git a/src/termhooks.h b/src/termhooks.h index 2b4011627c8..546a0d562b2 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -185,6 +185,7 @@ enum event_kind #endif , CONFIG_CHANGED_EVENT + , TAB_CHANGED_EVENT #ifdef WINDOWSNT /* Generated when an APPCOMMAND event is received, in response to diff --git a/src/xdisp.c b/src/xdisp.c index 9ece458e77e..12909627a2c 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -25256,7 +25256,7 @@ init_xdisp () current_header_line_height = current_mode_line_height = -1; CHARPOS (this_line_start_pos) = 0; - + mini_w = XWINDOW (minibuf_window); root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w))); diff --git a/src/xfns.c b/src/xfns.c index 45bea1e4ec2..7d3237966b1 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -5849,6 +5849,131 @@ frame_parm_handler x_frame_parm_handlers[] = x_set_sticky, }; +#ifdef USE_GTK +DEFUN ("tab-new", Ftab_new, + Stab_new, 0, 2, "", + doc: /* Create a new tab with name NAME in frame FRAME. +If NAME is nil, use a standard name (Page ). +FRAME nil means use the selected frame. + +Returns the key for the tab, which can be passed to `tab-delete'. */) + (name, frame) + Lisp_Object name, frame; +{ + FRAME_PTR f = check_x_frame (frame); + const char *key; + + if (!NILP (name) && !STRINGP (name)) + error ("Name is not string or nil"); + + BLOCK_INPUT; + key = xg_add_tab (f, NILP (name) ? NULL : SDATA (name)); + UNBLOCK_INPUT; + + return make_string (key, strlen (key)); +} + +DEFUN ("tab-delete", Ftab_delete, + Stab_delete, 0, 2, "", + doc: /* Remove tab KEY from frame FRAME. +KEY is what `tab-new' returned or nil, which means the current tab. +FRAME nil means use the selected frame. */) + (name, frame) + Lisp_Object name, frame; +{ + FRAME_PTR f = check_x_frame (frame); + if (!NILP (name) && !STRINGP (name)) + error ("Name is not string or nil"); + + BLOCK_INPUT; + xg_delete_tab (f, NILP (name) ? NULL : SDATA (name)); + UNBLOCK_INPUT; + + return Qnil; +} + +DEFUN ("tab-delete-other", Ftab_delete_other, + Stab_delete_other, 0, 1, "", + doc: /* Remove all tabs from frame FRAME except the current one. +FRAME nil means use the selected frame. */) + (frame) + Lisp_Object frame; +{ + FRAME_PTR f = check_x_frame (frame); + BLOCK_INPUT; + xg_delete_all_tabs (f); + UNBLOCK_INPUT; + + return Qnil; +} + +DEFUN ("tab-next", Ftab_next, + Stab_next, 0, 1, "", + doc: /* Go to the next tab on frame FRAME. +Wrap around to the beginning if current tab is last. +FRAME nil means use the selected frame. */) + (frame) + Lisp_Object frame; +{ + FRAME_PTR f = check_x_frame (frame); + BLOCK_INPUT; + xg_tab_next (f); + UNBLOCK_INPUT; + + return Qnil; +} + +DEFUN ("tab-previous", Ftab_previous, + Stab_previous, 0, 1, "", + doc: /* Go to the previous tab on frame FRAME. +Wrap around to the end if current tab is first. +FRAME nil means use the selected frame. */) + (frame) + Lisp_Object frame; +{ + FRAME_PTR f = check_x_frame (frame); + BLOCK_INPUT; + xg_tab_previous (f); + UNBLOCK_INPUT; + + return Qnil; +} + +DEFUN ("tab-set-label", Ftab_set_label, + Stab_set_label, 1, 2, 0, + doc: /* Set label for the current tab in frame FRAME to LABEL. +LABEL nil means use current buffer name. +FRAME nil means use the selected frame. */) + (label, frame) + Lisp_Object label, frame; +{ + FRAME_PTR f; + + if (NILP (frame)) + frame = selected_frame; + CHECK_LIVE_FRAME (frame); + f = XFRAME (frame); + if (! FRAME_X_P (f)) return; + + + if (NILP (label)) + { + if (!NILP (Fminibufferp (Qnil))) return; + label = Fbuffer_name (Qnil); + } + + if (!STRINGP (label)) + error ("label is not a string"); + + BLOCK_INPUT; + xg_set_tab_label (f, SDATA (label)); + UNBLOCK_INPUT; + + return Qnil; +} + +#endif + void syms_of_xfns () { @@ -5997,6 +6122,7 @@ the tool bar buttons. */); accepts --with-x-toolkit=gtk. */ Fprovide (intern_c_string ("x-toolkit"), Qnil); Fprovide (intern_c_string ("gtk"), Qnil); + Fprovide (intern_c_string ("tabs"), Qnil); DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string, doc: /* Version info for GTK+. */); @@ -6006,6 +6132,14 @@ the tool bar buttons. */); GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0); } + + defsubr (&Stab_new); + defsubr (&Stab_delete); + defsubr (&Stab_delete_other); + defsubr (&Stab_next); + defsubr (&Stab_previous); + defsubr (&Stab_set_label); + #endif /* USE_GTK */ /* X window properties. */ diff --git a/src/xftfont.c b/src/xftfont.c index 5d4581be4e9..e03b78471f8 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -672,6 +672,13 @@ xftfont_draw (s, from, to, x, y, with_background) int len = to - from; int i; + if (XftDrawDrawable (xft_draw) != s->window) + { + x_catch_errors (s->display); + XftDrawChange (xft_draw, s->window); + x_uncatch_errors (); + } + if (s->font == face->font) xftface_info = (struct xftface_info *) face->extra; xftfont_get_colors (f, face, s->gc, xftface_info, diff --git a/src/xterm.c b/src/xterm.c index fd09d6d4815..b43e6d11d64 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -6177,9 +6177,9 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) f->output_data.x->has_been_visible = 1; SET_FRAME_GARBAGED (f); } - else + else expose_frame (f, - event.xexpose.x, event.xexpose.y, + event.xexpose.x, event.xexpose.y, event.xexpose.width, event.xexpose.height); } else @@ -7225,6 +7225,9 @@ XTread_socket (terminal, expected, hold_quit) if (current_finish == X_EVENT_GOTO_OUT) break; } + + Ftab_set_label (Qnil, Qnil); + #endif /* USE_GTK */ out:; diff --git a/src/xterm.h b/src/xterm.h index a766f863c4d..846c6df4a11 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -474,6 +474,8 @@ struct x_output GtkWidget *edit_widget; /* The widget used for laying out widgets vertically. */ GtkWidget *vbox_widget; + /* The notebook (i.e. tab) widget. */ + GtkWidget *notebook_widget; /* The menubar in this frame. */ GtkWidget *menubar_widget; /* The tool bar in this frame */