Skip to content

Commit

Permalink
TerminalWidget: port event handling to event controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
Marukesu authored and danirabbit committed Nov 6, 2023
1 parent c5dfcd3 commit 7a62bc7
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 73 deletions.
2 changes: 1 addition & 1 deletion src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace Terminal {
private HashTable<string, TerminalWidget> restorable_terminals;
private bool is_fullscreen = false;
private bool on_drag = false;
private uint focus_timeout = 0;

private const int NORMAL = 0;
private const int MAXIMIZED = 1;
Expand All @@ -41,7 +42,6 @@ namespace Terminal {
public bool focus_restored_tabs { get; construct; default = true; }
public bool recreate_tabs { get; construct; default = true; }
public bool restore_pos { get; construct; default = true; }
public uint focus_timeout { get; private set; default = 0;}
public Gtk.Menu menu { get; private set; }
public Terminal.Application app { get; construct; }
public SimpleActionGroup actions { get; construct; }
Expand Down
160 changes: 88 additions & 72 deletions src/Widgets/TerminalWidget.vala
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,12 @@ namespace Terminal {
private long remembered_command_end_row = 0; /* Only need to remember row at the moment */
public bool last_key_was_return = true;

private double total_delta_y = 0.0;
private Gtk.EventControllerMotion motion_controller;
private Gtk.EventControllerScroll scroll_controller;
private Gtk.EventControllerKey key_controller;
private Gtk.GestureMultiPress press_gesture;

private double scroll_delta = 0.0;

public signal void cwd_changed ();

Expand Down Expand Up @@ -155,81 +160,32 @@ namespace Terminal {
Application.settings.changed["prefer-dark-style"].connect (update_theme);
Application.settings.changed["theme"].connect (update_theme);

button_press_event.connect ((event) => {
link_uri = null;
/* If this event caused focus-in then window.focus_timeout is > 0
* and we need to suppress following hyperlinks on button release.
* If focus-in was caused by keyboard then the focus_timeout will have
* expired and we can follow hyperlinks */
allow_hyperlink = window.focus_timeout == 0;

if (event.button == Gdk.BUTTON_SECONDARY) {
link_uri = get_link (event);
if (link_uri != null) {
window.get_simple_action (MainWindow.ACTION_COPY).set_enabled (true);
}

window.update_context_menu ();

menu.popup_at_pointer (event);
menu.select_first (false);

return true;
}

return false;
});

button_release_event.connect ((event) => {

if (event.button == Gdk.BUTTON_PRIMARY) {
if (allow_hyperlink) {
link_uri = get_link (event);
motion_controller = new Gtk.EventControllerMotion (this) {
propagation_phase = CAPTURE
};
motion_controller.enter.connect (pointer_focus);

if (link_uri != null && !get_has_selection ()) {
window.get_simple_action (MainWindow.ACTION_OPEN_IN_BROWSER).activate (null);
}
} else {
allow_hyperlink = true;
}
}
scroll_controller = new Gtk.EventControllerScroll (this, NONE) {
propagation_phase = TARGET
};
scroll_controller.scroll.connect (scroll);
scroll_controller.scroll_end.connect (() => scroll_delta = 0.0);

return false;
});
key_controller = new Gtk.EventControllerKey (this) {
propagation_phase = NONE
};
key_controller.key_pressed.connect (key_pressed);
key_controller.key_released.connect (() => scroll_controller.flags = NONE);

scroll_event.connect ((event) => {
if ((event.state & Gdk.ModifierType.CONTROL_MASK) > 0) {
switch (event.direction) {
case Gdk.ScrollDirection.UP:
window.get_simple_action (MainWindow.ACTION_ZOOM_IN_FONT).activate (null);
return Gdk.EVENT_STOP;

case Gdk.ScrollDirection.DOWN:
window.get_simple_action (MainWindow.ACTION_ZOOM_OUT_FONT).activate (null);
return Gdk.EVENT_STOP;

case Gdk.ScrollDirection.SMOOTH:
/* try to emulate a normal scrolling event by summing deltas.
* step size of 0.5 chosen to match sensitivity */
total_delta_y += event.delta_y;

if (total_delta_y >= 0.5) {
total_delta_y = 0;
window.get_simple_action (MainWindow.ACTION_ZOOM_OUT_FONT).activate (null);
} else if (total_delta_y <= -0.5) {
total_delta_y = 0;
window.get_simple_action (MainWindow.ACTION_ZOOM_IN_FONT).activate (null);
}

return Gdk.EVENT_STOP;

default:
break;
}
}
press_gesture = new Gtk.GestureMultiPress (this) {
propagation_phase = TARGET,
button = 0
};
press_gesture.pressed.connect (button_pressed);
press_gesture.released.connect (button_released);

return Gdk.EVENT_PROPAGATE;
});
// send events to key controller manually, since key_released isn't emitted in any propagation phase
event.connect (key_controller.handle_event);

selection_changed.connect (() => {
window.get_simple_action (MainWindow.ACTION_COPY).set_enabled (get_has_selection ());
Expand Down Expand Up @@ -261,6 +217,66 @@ namespace Terminal {
this.clickable (REGEX_STRINGS);
}

private void pointer_focus () {
// If this event caused focus-in then we need to suppress following hyperlinks on button release.
allow_hyperlink = has_focus;
}

private void button_pressed (Gtk.GestureMultiPress gesture, int n_press, double x, double y) {
link_uri = null;

if (gesture.get_current_button () == Gdk.BUTTON_SECONDARY) {
link_uri = get_link (gesture.get_last_event (null));

if (link_uri != null) {
window.get_simple_action (MainWindow.ACTION_COPY).set_enabled (true);
}

Gdk.Rectangle rect = { (int) x, (int) y };
window.update_context_menu ();

menu.popup_at_rect (get_window (), rect, SOUTH_WEST, NORTH_WEST);
menu.select_first (false);

gesture.set_state (CLAIMED);
}
}

private void button_released (Gtk.GestureMultiPress gesture, int n_press, double x, double y) {
if (gesture.get_current_button () == Gdk.BUTTON_PRIMARY) {
if (allow_hyperlink) {
link_uri = get_link (gesture.get_last_event (null));

if (link_uri != null && !get_has_selection ()) {
window.get_simple_action (MainWindow.ACTION_OPEN_IN_BROWSER).activate (null);
}
} else {
allow_hyperlink = true;
}
}
}

private void scroll (double x, double y) {
// try to emulate a normal scrolling event by summing deltas. step size of 0.5 chosen to match sensitivity
scroll_delta += y;

if (scroll_delta >= 0.5) {
window.get_simple_action (MainWindow.ACTION_ZOOM_OUT_FONT).activate (null);
scroll_delta = 0.0;
} else if (scroll_delta <= -0.5) {
window.get_simple_action (MainWindow.ACTION_ZOOM_IN_FONT).activate (null);
scroll_delta = 0.0;
}
}

private bool key_pressed (uint keyval, uint keycode, Gdk.ModifierType modifiers) {
if (keyval == Gdk.Key.Control_R || keyval == Gdk.Key.Control_L) {
scroll_controller.flags = VERTICAL;
}

return false;
}

private void update_theme () {
var gtk_settings = Gtk.Settings.get_default ();
var theme_palette = new Gdk.RGBA[Themes.PALETTE_SIZE];
Expand Down

0 comments on commit 7a62bc7

Please sign in to comment.