aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJuhani Krekelä2021-06-25 17:59:53 +0300
committerWolfgang Müller2021-06-26 12:12:45 +0200
commitb70083a5f4404e2422ff0a0aadd023a661164fae (patch)
treed700ce1ff3e07ff73e05ca41387ca88d11633e28
parentb497a49d8bd2a345dd30a9f55dc4976560df157f (diff)
downloadweltschmerz-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.ui18
-rw-r--r--terminal.vala49
-rw-r--r--weltschmerz.18
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 .