diff options
author | Juhani Krekelä | 2021-06-25 17:59:53 +0300 |
---|---|---|
committer | Wolfgang Müller | 2021-06-26 12:12:45 +0200 |
commit | b70083a5f4404e2422ff0a0aadd023a661164fae (patch) | |
tree | d700ce1ff3e07ff73e05ca41387ca88d11633e28 | |
parent | b497a49d8bd2a345dd30a9f55dc4976560df157f (diff) | |
download | weltschmerz-b70083a5f4404e2422ff0a0aadd023a661164fae.tar.gz |
Add feature to open a new terminal
Add ability to open a new weltschmerz terminal, either from context menu or
with a key combination. The new terminal is opened in the directory
indicated with OSC 7, allowing quickly opening additional terminals while
working.
Preferably this would launch the user's preferred terminal, as defined
in per-user settings, but this is not possible with glib[1]. For this
reason the option always launches another weltschmerz.
weltschmerz is launched using bare Process.spawn_async() on the name of the
program as defined in weltschmerz.vala. We considered using the AppInfo
database to retrieve the name of executable instead, but as there is no way
to query the database for terminal emulators we would have to go through
every single program installed on the computer and try to find one called
weltschmerz. As the change would merely replace the requirement of having
weltschmerz in PATH with the requirement of having a .desktop file with the
name in one of the standardized locations, this would not be worth it.
[1] https://gitlab.gnome.org/GNOME/glib/-/issues/338
-rw-r--r-- | terminal.ui | 18 | ||||
-rw-r--r-- | terminal.vala | 49 | ||||
-rw-r--r-- | weltschmerz.1 | 8 |
3 files changed, 74 insertions, 1 deletions
diff --git a/terminal.ui b/terminal.ui index c22fbec..345c543 100644 --- a/terminal.ui +++ b/terminal.ui @@ -52,6 +52,11 @@ <property name="can-focus">False</property> <property name="icon-name">document-open</property> </object> + <object class="GtkImage" id="open_terminal_item_image"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">utilities-terminal</property> + </object> <object class="GtkMenu" id="standard_context_menu"> <property name="visible">True</property> <property name="can-focus">False</property> @@ -93,6 +98,19 @@ </object> </child> <child> + <object class="GtkImageMenuItem" id="open_terminal_item"> + <property name="label" translatable="yes">Open _terminal</property> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="tooltip-text" translatable="yes">Open new terminal window in the current directory</property> + <property name="use-underline">True</property> + <property name="image">open_terminal_item_image</property> + <property name="use-stock">False</property> + <signal name="activate" handler="open_terminal" swapped="no"/> + <accelerator key="t" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/> + </object> + </child> + <child> <object class="GtkImageMenuItem" id="open_directory_item"> <property name="label" translatable="yes">_Open directory</property> <property name="visible">True</property> diff --git a/terminal.vala b/terminal.vala index 4a2e676..dfe8130 100644 --- a/terminal.vala +++ b/terminal.vala @@ -28,6 +28,7 @@ class Terminal : Gtk.Overlay { [GtkChild] unowned Gtk.Menu hyperlink_context_menu; [GtkChild] unowned Gtk.MenuItem copy_item_text; [GtkChild] unowned Gtk.MenuItem copy_item_html; + [GtkChild] unowned Gtk.MenuItem open_terminal_item; [GtkChild] unowned Gtk.MenuItem open_directory_item; [GtkChild] unowned Gtk.Revealer search_revealer; [GtkChild] unowned Gtk.ScrolledWindow scrolled_window; @@ -329,6 +330,48 @@ class Terminal : Gtk.Overlay { adjust_font_scale(vte.get_font_scale() / FONT_SCALE_FACTOR); } + string? get_local_directory_path() { + var uri = vte.get_current_directory_uri(); + if (uri == null) + return null; + + string uri_hostname; + string path = null; + try { + path = Filename.from_uri(uri, out uri_hostname); + } catch (Error e) { + warning(e.message); + return null; + } + + char hostname[256]; // SUSv2 says 255 is max length, +1 for terminator + Posix.gethostname(hostname); + + // If the path URI points to another computer, return null + if (uri_hostname != (string)hostname) + return null; + + return path; + } + + [GtkCallback] + void open_terminal() { + var cwd = get_local_directory_path(); + if (cwd == null) + return; + + Pid child; + + try { + Process.spawn_async(cwd, {PROGRAM_NAME}, Environ.get(), SpawnFlags.SEARCH_PATH, null, out child); + } catch (Error e) { + warning(e.message); + infobar_show(e.message, Gtk.MessageType.ERROR); + } + + Process.close_pid(child); + } + [GtkCallback] void open_directory() { uri_open(vte.get_current_directory_uri()); @@ -358,6 +401,7 @@ class Terminal : Gtk.Overlay { } else { copy_item_text.set_sensitive(vte.get_has_selection()); copy_item_html.set_sensitive(vte.get_has_selection()); + open_terminal_item.set_sensitive(get_local_directory_path() != null); open_directory_item.set_sensitive(vte.get_current_directory_uri() != null); standard_context_menu.popup_at_pointer(event); } @@ -408,6 +452,11 @@ class Terminal : Gtk.Overlay { return true; } + if (match_key(event, CONTROL_MASK | SHIFT_MASK, Gdk.Key.T)) { + open_terminal(); + return true; + } + if (match_key(event, CONTROL_MASK | SHIFT_MASK, Gdk.Key.O)) { open_directory(); return true; diff --git a/weltschmerz.1 b/weltschmerz.1 index 3c92ef6..a00894e 100644 --- a/weltschmerz.1 +++ b/weltschmerz.1 @@ -1,4 +1,4 @@ -.Dd June 17, 2021 +.Dd June 25, 2021 .Dt WELTSCHMERZ 1 .Os .Sh NAME @@ -52,6 +52,12 @@ Note that relies on proper support of OSC 7 to do this. If the child program (such as the shell or an editor) does not send OSC 7, this feature will not work. +.Pp +A new terminal window can likewise be opened in the program's current directory with +.Sy CTRL + Shift + T . +The limitations of +.Sy CTRL + Shift + O +also apply here. .Sh SEARCH OVERLAY The search overlay can be opened by pressing .Sy CTRL + Shift + F . |