[vte] widget: Use a input-only window
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] widget: Use a input-only window
- Date: Sat, 26 Dec 2015 18:34:59 +0000 (UTC)
commit 0612f4005c711f7a4fe9133b9555a723689885f4
Author: Christian Persch <chpe gnome org>
Date: Sat Dec 26 19:34:36 2015 +0100
widget: Use a input-only window
We don't need a output window, just an input window so we can handle events.
https://bugzilla.gnome.org/show_bug.cgi?id=734920
src/app.vala | 5 ++
src/vte.cc | 123 +++++++++++++++++++++++-----------------------------
src/vtegtk.cc | 33 +++++++++++++-
src/vteinternal.hh | 5 ++
4 files changed, 96 insertions(+), 70 deletions(-)
---
diff --git a/src/app.vala b/src/app.vala
index 0dcb3b9..2362d09 100644
--- a/src/app.vala
+++ b/src/app.vala
@@ -233,6 +233,11 @@ class Window : Gtk.ApplicationWindow
/* Create terminal and connect scrollbar */
terminal = new Vte.Terminal();
+ terminal.margin_start = 20;
+ terminal.margin_end = 20;
+ terminal.margin_top = 30;
+ terminal.margin_bottom = 30;
+
scrollbar.set_adjustment(terminal.get_vadjustment());
/* Create actions */
diff --git a/src/vte.cc b/src/vte.cc
index fdebe52..1d0e72e 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -377,9 +377,12 @@ VteTerminalPrivate::invalidate_cells(vte::grid::column_t column_start,
* case updates are coming in really soon. */
add_update_timeout (m_terminal);
} else {
- rect.x += m_padding.left;
- rect.y += m_padding.top;
- gdk_window_invalidate_rect (gtk_widget_get_window (m_widget), &rect, FALSE);
+ auto allocation = get_allocated_rect();
+ rect.x += allocation.x + m_padding.left;
+ rect.y += allocation.y + m_padding.top;
+ cairo_region_t *region = cairo_region_create_rectangle(&rect);
+ gtk_widget_queue_draw_region(m_widget, region);
+ cairo_region_destroy(region);
}
_vte_debug_print (VTE_DEBUG_WORK, "!");
@@ -420,8 +423,6 @@ VteTerminalPrivate::invalidate(vte::grid::span const& s,
void
VteTerminalPrivate::invalidate_all()
{
- cairo_rectangle_int_t rect;
-
if (G_UNLIKELY (!widget_realized()))
return;
@@ -432,22 +433,24 @@ VteTerminalPrivate::invalidate_all()
_vte_debug_print (VTE_DEBUG_WORK, "*");
_vte_debug_print (VTE_DEBUG_UPDATES, "Invalidating all.\n");
- auto allocation = get_allocated_rect();
-
/* replace invalid regions with one covering the whole terminal */
reset_update_rects();
- rect.x = rect.y = 0;
- rect.width = allocation.width;
- rect.height = allocation.height;
m_invalidated_all = TRUE;
if (m_active != NULL) {
+ auto allocation = get_allocated_rect();
+ cairo_rectangle_int_t rect;
+ rect.x = -m_padding.left;
+ rect.y = -m_padding.top;
+ rect.width = allocation.width;
+ rect.height = allocation.height;
+
g_array_append_val(m_update_rects, rect);
/* Wait a bit before doing any invalidation, just in
* case updates are coming in really soon. */
add_update_timeout (m_terminal);
} else {
- gdk_window_invalidate_rect (gtk_widget_get_window (m_widget), &rect, FALSE);
+ gtk_widget_queue_draw(m_widget);
}
}
@@ -1070,7 +1073,7 @@ VteTerminalPrivate::set_cursor_from_regex_match(struct vte_match_regex *regex)
return;
}
- gdk_window_set_cursor(gtk_widget_get_window(m_widget), gdk_cursor);
+ gdk_window_set_cursor(m_event_window, gdk_cursor);
if (gdk_cursor)
g_object_unref(gdk_cursor);
@@ -1836,7 +1839,7 @@ VteTerminalPrivate::view_coords_from_event(GdkEvent const* event) const
{
double x, y;
if (event == nullptr ||
- ((reinterpret_cast<GdkEventAny const*>(event))->window != gtk_widget_get_window(m_widget)) ||
+ ((reinterpret_cast<GdkEventAny const*>(event))->window != m_event_window) ||
!gdk_event_get_coords(event, &x, &y))
return vte::view::coords(-1, -1);
@@ -2479,13 +2482,11 @@ VteTerminalPrivate::set_pointer_visible(bool visible)
if (!widget_realized())
return;
- GdkWindow *window = gtk_widget_get_window(m_widget);
-
if (visible || !m_mouse_autohide) {
if (m_mouse_tracking_mode) {
_vte_debug_print(VTE_DEBUG_CURSOR,
"Setting mousing cursor.\n");
- gdk_window_set_cursor(window, m_mouse_mousing_cursor);
+ gdk_window_set_cursor(m_event_window, m_mouse_mousing_cursor);
} else
if ( (guint)m_match_tag < m_match_regexes->len) {
struct vte_match_regex *regex =
@@ -2496,12 +2497,12 @@ VteTerminalPrivate::set_pointer_visible(bool visible)
} else {
_vte_debug_print(VTE_DEBUG_CURSOR,
"Setting default mouse cursor.\n");
- gdk_window_set_cursor(window, m_mouse_default_cursor);
+ gdk_window_set_cursor(m_event_window, m_mouse_default_cursor);
}
} else {
_vte_debug_print(VTE_DEBUG_CURSOR,
"Setting to invisible cursor.\n");
- gdk_window_set_cursor (window, m_mouse_inviso_cursor);
+ gdk_window_set_cursor(m_event_window, m_mouse_inviso_cursor);
}
}
@@ -8298,7 +8299,7 @@ VteTerminalPrivate::widget_size_allocate(GtkAllocation *allocation)
/* Resize the GDK window. */
if (widget_realized()) {
- gdk_window_move_resize(gtk_widget_get_window(m_widget),
+ gdk_window_move_resize(m_event_window,
allocation->x,
allocation->y,
allocation->width,
@@ -8316,8 +8317,6 @@ VteTerminalPrivate::widget_unrealize()
{
_vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_unrealize()\n");
- GdkWindow *window = gtk_widget_get_window(m_widget);
-
/* Deallocate the cursors. */
m_mouse_cursor_visible = FALSE;
g_object_unref(m_mouse_default_cursor);
@@ -8364,14 +8363,6 @@ VteTerminalPrivate::widget_unrealize()
gtk_widget_unmap(m_widget);
}
- /* Remove the GDK window. */
- if (window != NULL) {
- gdk_window_set_user_data (window, NULL);
- gtk_widget_set_window(m_widget, NULL);
-
- gdk_window_destroy (window);
- }
-
/* Remove the blink timeout function. */
remove_cursor_timeout();
@@ -8388,8 +8379,10 @@ VteTerminalPrivate::widget_unrealize()
/* Clear modifiers. */
m_modifiers = 0;
- /* Mark that we no longer have a GDK window. */
- gtk_widget_set_realized(m_widget, FALSE);
+ /* Destroy the even window */
+ gtk_widget_unregister_window(m_widget, m_event_window);
+ gdk_window_destroy(m_event_window);
+ m_event_window = nullptr;
}
static void
@@ -8622,10 +8615,6 @@ VteTerminalPrivate::~VteTerminalPrivate()
void
VteTerminalPrivate::widget_realize()
{
- GdkWindow *window;
- GdkWindowAttr attributes;
- guint attributes_mask = 0;
-
_vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_realize()\n");
auto allocation = get_allocated_rect();
@@ -8634,14 +8623,16 @@ VteTerminalPrivate::widget_realize()
m_mouse_cursor_visible = TRUE;
m_mouse_default_cursor = widget_cursor_new(VTE_DEFAULT_CURSOR);
m_mouse_mousing_cursor = widget_cursor_new(VTE_MOUSING_CURSOR);
+ m_mouse_inviso_cursor = widget_cursor_new(GDK_BLANK_CURSOR);
/* Create a GDK window for the widget. */
+ GdkWindowAttr attributes;
attributes.window_type = GDK_WINDOW_CHILD;
attributes.x = allocation.x;
attributes.y = allocation.y;
attributes.width = allocation.width;
attributes.height = allocation.height;
- attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.wclass = GDK_INPUT_ONLY;
attributes.visual = gtk_widget_get_visual(m_widget);
attributes.event_mask = gtk_widget_get_events(m_widget) |
GDK_EXPOSURE_MASK |
@@ -8658,23 +8649,14 @@ VteTerminalPrivate::widget_realize()
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK;
attributes.cursor = m_mouse_default_cursor;
- attributes_mask = GDK_WA_X |
- GDK_WA_Y |
- (attributes.visual ? GDK_WA_VISUAL : 0) |
- GDK_WA_CURSOR;
-
- window = gdk_window_new(gtk_widget_get_parent_window (m_widget),
- &attributes, attributes_mask);
+ guint attributes_mask = GDK_WA_X |
+ GDK_WA_Y |
+ (attributes.visual ? GDK_WA_VISUAL : 0) |
+ GDK_WA_CURSOR;
- gtk_widget_set_window(m_widget, window);
- gdk_window_set_user_data(window, m_widget);
- //FIXMEchpe this is obsolete
- gtk_style_context_set_background(gtk_widget_get_style_context(m_widget), window);
- //FIXMEchpe move this to class init
- _VTE_DEBUG_IF (VTE_DEBUG_UPDATES) gdk_window_set_debug_updates (TRUE);
-
- /* Set the realized flag. */
- gtk_widget_set_realized(m_widget, TRUE);
+ m_event_window = gdk_window_new(gtk_widget_get_parent_window (m_widget),
+ &attributes, attributes_mask);
+ gtk_widget_register_window(m_widget, m_event_window);
/* Create rendering data if this is a re-realise */
if (m_draw == NULL) {
@@ -8693,7 +8675,7 @@ VteTerminalPrivate::widget_realize()
}
m_im_preedit_active = FALSE;
m_im_context = gtk_im_multicontext_new();
- gtk_im_context_set_client_window(m_im_context, window);
+ gtk_im_context_set_client_window(m_im_context, m_event_window);
g_signal_connect(m_im_context, "commit",
G_CALLBACK(vte_terminal_im_commit_cb), this);
g_signal_connect(m_im_context, "preedit-start",
@@ -8711,15 +8693,26 @@ VteTerminalPrivate::widget_realize()
/* Clear modifiers. */
m_modifiers = 0;
- /* Create our invisible cursor. */
- m_mouse_inviso_cursor = widget_cursor_new(GDK_BLANK_CURSOR);
-
/* Make sure the style is set, bug 727614. */
widget_style_updated();
ensure_font();
}
+void
+VteTerminalPrivate::widget_map()
+{
+ if (m_event_window)
+ gdk_window_show_unraised(m_event_window);
+}
+
+void
+VteTerminalPrivate::widget_unmap()
+{
+ if (m_event_window)
+ gdk_window_hide(m_event_window);
+}
+
static inline void
swap (guint *a, guint *b)
{
@@ -10669,8 +10662,6 @@ vte_terminal_start_processing (VteTerminal *terminal)
void
VteTerminalPrivate::emit_pending_signals()
{
- GdkWindow *window = gtk_widget_get_window(m_widget);
-
GObject *object = G_OBJECT(m_terminal);
g_object_freeze_notify(object);
@@ -10681,8 +10672,6 @@ VteTerminalPrivate::emit_pending_signals()
m_window_title = m_window_title_changed;
m_window_title_changed = NULL;
- if (window)
- gdk_window_set_title (window, m_window_title);
_vte_debug_print(VTE_DEBUG_SIGNALS,
"Emitting `window-title-changed'.\n");
g_signal_emit(object, signals[SIGNAL_WINDOW_TITLE_CHANGED], 0);
@@ -10694,8 +10683,6 @@ VteTerminalPrivate::emit_pending_signals()
m_icon_title = m_icon_title_changed;
m_icon_title_changed = NULL;
- if (window)
- gdk_window_set_icon_name (window, m_icon_title);
_vte_debug_print(VTE_DEBUG_SIGNALS,
"Emitting `icon-title-changed'.\n");
g_signal_emit(object, signals[SIGNAL_ICON_TITLE_CHANGED], 0);
@@ -10881,8 +10868,6 @@ process_timeout (gpointer data)
static gboolean
update_regions (VteTerminal *terminal)
{
- GdkWindow *window;
-
if (G_UNLIKELY(!terminal->pvt->widget_realized()))
return FALSE;
if (terminal->pvt->visibility_state == GDK_VISIBILITY_FULLY_OBSCURED) {
@@ -10902,16 +10887,16 @@ update_regions (VteTerminal *terminal)
g_array_set_size(terminal->pvt->m_update_rects, 0);
terminal->pvt->invalidated_all = FALSE;
+ auto allocation = terminal->pvt->get_allocated_rect();
cairo_region_translate(region,
- terminal->pvt->m_padding.left,
- terminal->pvt->m_padding.top);
+ allocation.x + terminal->pvt->m_padding.left,
+ allocation.y + terminal->pvt->m_padding.top);
/* and perform the merge with the window visible area */
- window = gtk_widget_get_window (&terminal->widget);
- gdk_window_invalidate_region (window, region, FALSE);
+ gtk_widget_queue_draw_region(&terminal->widget, region);
cairo_region_destroy (region);
- gdk_window_process_updates (window, FALSE);
+ gdk_window_process_updates(gtk_widget_get_window(&terminal->widget), FALSE);
_vte_debug_print (VTE_DEBUG_WORK, "-");
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 073c308..d7c4ec4 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -284,6 +284,8 @@ vte_terminal_draw(GtkWidget *widget,
static void
vte_terminal_realize(GtkWidget *widget)
{
+ GTK_WIDGET_CLASS(vte_terminal_parent_class)->realize(widget);
+
VteTerminal *terminal= VTE_TERMINAL(widget);
terminal->pvt->widget_realize();
}
@@ -293,8 +295,31 @@ vte_terminal_unrealize(GtkWidget *widget)
{
VteTerminal *terminal = VTE_TERMINAL (widget);
terminal->pvt->widget_unrealize();
+
+ GTK_WIDGET_CLASS(vte_terminal_parent_class)->unrealize(widget);
}
+static void
+vte_terminal_map(GtkWidget *widget)
+{
+ _vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_map()\n");
+
+ VteTerminal *terminal = VTE_TERMINAL(widget);
+ GTK_WIDGET_CLASS(vte_terminal_parent_class)->map(widget);
+
+ terminal->pvt->widget_map();
+}
+
+static void
+vte_terminal_unmap(GtkWidget *widget)
+{
+ _vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_unmap()\n");
+
+ VteTerminal *terminal = VTE_TERMINAL(widget);
+ terminal->pvt->widget_unmap();
+
+ GTK_WIDGET_CLASS(vte_terminal_parent_class)->unmap(widget);
+}
static void
vte_terminal_screen_changed (GtkWidget *widget,
@@ -325,6 +350,8 @@ vte_terminal_init(VteTerminal *terminal)
/* Initialize private data. NOTE: place is zeroed */
place = G_TYPE_INSTANCE_GET_PRIVATE (terminal, VTE_TYPE_TERMINAL, VteTerminalPrivate);
terminal->pvt = new (place) VteTerminalPrivate(terminal);
+
+ gtk_widget_set_has_window(&terminal->widget, FALSE);
}
static void
@@ -557,6 +584,8 @@ vte_terminal_class_init(VteTerminalClass *klass)
}
#endif
+ _VTE_DEBUG_IF (VTE_DEBUG_UPDATES) gdk_window_set_debug_updates(TRUE);
+
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
#ifdef HAVE_DECL_BIND_TEXTDOMAIN_CODESET
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
@@ -572,6 +601,9 @@ vte_terminal_class_init(VteTerminalClass *klass)
gobject_class->get_property = vte_terminal_get_property;
gobject_class->set_property = vte_terminal_set_property;
widget_class->realize = vte_terminal_realize;
+ widget_class->unrealize = vte_terminal_unrealize;
+ widget_class->map = vte_terminal_map;
+ widget_class->unmap = vte_terminal_unmap;
widget_class->scroll_event = vte_terminal_scroll;
widget_class->draw = vte_terminal_draw;
widget_class->key_press_event = vte_terminal_key_press;
@@ -584,7 +616,6 @@ vte_terminal_class_init(VteTerminalClass *klass)
widget_class->focus_in_event = vte_terminal_focus_in;
widget_class->focus_out_event = vte_terminal_focus_out;
widget_class->visibility_notify_event = vte_terminal_visibility_notify;
- widget_class->unrealize = vte_terminal_unrealize;
widget_class->style_updated = vte_terminal_style_updated;
widget_class->get_preferred_width = vte_terminal_get_preferred_width;
widget_class->get_preferred_height = vte_terminal_get_preferred_height;
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 8826ccd..204bed9 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -194,6 +194,9 @@ public:
VteTerminal *m_terminal;
GtkWidget *m_widget;
+ /* Event window */
+ GdkWindow *m_event_window;
+
/* Metric and sizing data: dimensions of the window */
glong row_count;
glong column_count;
@@ -554,6 +557,8 @@ public:
void widget_realize();
void widget_unrealize();
+ void widget_map();
+ void widget_unmap();
void widget_style_updated();
void widget_focus_in(GdkEventFocus *event);
void widget_focus_out(GdkEventFocus *event);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]