mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-05-23 21:30:19 +00:00
feat: add +toggle-quick-terminal IPC command
Expose toggle-quick-terminal as a proper IPC action so it can be triggered via 'ghostty +toggle-quick-terminal' from the command line, instead of calling the raw D-Bus org.gtk.Actions.Activate interface. This follows the same pattern as the existing +new-window IPC command: - Add toggle_quick_terminal to apprt.ipc.Action enum (Zig + C ABI) - Create apprt/gtk/ipc/toggle_quick_terminal.zig (GTK D-Bus handler) - Route .toggle_quick_terminal in apprt/gtk/App.zig performIpc - Register toggle-quick-terminal GAction in application.zig - Add +toggle-quick-terminal CLI handler in cli/ - Register in cli/ghostty.zig Action enum, runMain, and options - Add stub in apprt/embedded.zig - Update include/ghostty.h C header enum Usage: ghostty +toggle-quick-terminal Closes: #12618
This commit is contained in:
@@ -1054,6 +1054,7 @@ typedef union {
|
||||
// apprt.ipc.Action.Key
|
||||
typedef enum {
|
||||
GHOSTTY_IPC_ACTION_NEW_WINDOW,
|
||||
GHOSTTY_IPC_ACTION_TOGGLE_QUICK_TERMINAL,
|
||||
} ghostty_ipc_action_tag_e;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -336,6 +336,7 @@ pub const App = struct {
|
||||
) (Allocator.Error || std.posix.WriteError || apprt.ipc.Errors)!bool {
|
||||
switch (action) {
|
||||
.new_window => return false,
|
||||
.toggle_quick_terminal => return false,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ const CoreApp = @import("../../App.zig");
|
||||
const Application = @import("class/application.zig").Application;
|
||||
const Surface = @import("Surface.zig");
|
||||
const ipcNewWindow = @import("ipc/new_window.zig").newWindow;
|
||||
const ipcToggleQuickTerminal = @import("ipc/toggle_quick_terminal.zig").toggleQuickTerminal;
|
||||
|
||||
const log = std.log.scoped(.gtk);
|
||||
|
||||
@@ -84,6 +85,7 @@ pub fn performIpc(
|
||||
) !bool {
|
||||
switch (action) {
|
||||
.new_window => return try ipcNewWindow(alloc, target, value),
|
||||
.toggle_quick_terminal => return try ipcToggleQuickTerminal(alloc, target),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1419,6 +1419,7 @@ pub const Application = extern struct {
|
||||
.init("present-surface", actionPresentSurface, t_variant_type),
|
||||
.init("quit", actionQuit, null),
|
||||
.init("reload-config", actionReloadConfig, null),
|
||||
.init("toggle-quick-terminal", actionToggleQuickTerminal, null),
|
||||
};
|
||||
|
||||
ext.actions.add(Self, self, &actions);
|
||||
@@ -1669,6 +1670,17 @@ pub const Application = extern struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn actionToggleQuickTerminal(
|
||||
_: *gio.SimpleAction,
|
||||
_: ?*glib.Variant,
|
||||
self: *Self,
|
||||
) callconv(.c) void {
|
||||
const priv = self.private();
|
||||
priv.core_app.performAction(self.rt(), .toggle_quick_terminal) catch |err| {
|
||||
log.warn("error toggling quick terminal err={}", .{err});
|
||||
};
|
||||
}
|
||||
|
||||
fn actionQuit(
|
||||
_: *gio.SimpleAction,
|
||||
_: ?*glib.Variant,
|
||||
|
||||
24
src/apprt/gtk/ipc/toggle_quick_terminal.zig
Normal file
24
src/apprt/gtk/ipc/toggle_quick_terminal.zig
Normal file
@@ -0,0 +1,24 @@
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const apprt = @import("../../../apprt.zig");
|
||||
const DBus = @import("DBus.zig");
|
||||
|
||||
/// Use a D-Bus method call to toggle the quick terminal on GTK.
|
||||
///
|
||||
/// `ghostty +toggle-quick-terminal` is equivalent to the following command
|
||||
/// (on a release build):
|
||||
///
|
||||
/// ```sh
|
||||
/// gdbus call --session \
|
||||
/// --dest com.mitchellh.ghostty \
|
||||
/// --object-path /com/mitchellh/ghostty \
|
||||
/// --method org.gtk.Actions.Activate \
|
||||
/// toggle-quick-terminal [] []
|
||||
/// ```
|
||||
pub fn toggleQuickTerminal(alloc: Allocator, target: apprt.ipc.Target) (Allocator.Error || std.Io.Writer.Error || apprt.ipc.Errors)!bool {
|
||||
var dbus = try DBus.init(alloc, target, "toggle-quick-terminal");
|
||||
defer dbus.deinit(alloc);
|
||||
try dbus.send();
|
||||
return true;
|
||||
}
|
||||
@@ -73,6 +73,9 @@ pub const Action = union(enum) {
|
||||
/// The arguments to pass to Ghostty as the command.
|
||||
new_window: NewWindow,
|
||||
|
||||
/// Toggle the quick terminal.
|
||||
toggle_quick_terminal: void,
|
||||
|
||||
pub const NewWindow = struct {
|
||||
/// A list of command arguments to launch in the new window. If this is
|
||||
/// `null` the command configured in the config or the user's default
|
||||
@@ -113,6 +116,7 @@ pub const Action = union(enum) {
|
||||
/// Sync with: ghostty_ipc_action_tag_e
|
||||
pub const Key = enum(c_int) {
|
||||
new_window,
|
||||
toggle_quick_terminal,
|
||||
|
||||
test "ghostty.h Action.Key" {
|
||||
try lib.checkGhosttyHEnum(Key, "GHOSTTY_IPC_ACTION_");
|
||||
|
||||
@@ -20,6 +20,7 @@ const crash_report = @import("crash_report.zig");
|
||||
const show_face = @import("show_face.zig");
|
||||
const boo = @import("boo.zig");
|
||||
const new_window = @import("new_window.zig");
|
||||
const toggle_quick_terminal = @import("toggle_quick_terminal.zig");
|
||||
|
||||
/// Special commands that can be invoked via CLI flags. These are all
|
||||
/// invoked by using `+<action>` as a CLI flag. The only exception is
|
||||
@@ -73,6 +74,9 @@ pub const Action = enum {
|
||||
// Use IPC to tell the running Ghostty to open a new window.
|
||||
@"new-window",
|
||||
|
||||
// Use IPC to tell the running Ghostty to toggle the quick terminal.
|
||||
@"toggle-quick-terminal",
|
||||
|
||||
pub fn detectSpecialCase(arg: []const u8) ?SpecialCase(Action) {
|
||||
// If we see a "-e" and we haven't seen a command yet, then
|
||||
// we are done looking for commands. This special case enables
|
||||
@@ -152,6 +156,7 @@ pub const Action = enum {
|
||||
.@"show-face" => try show_face.run(alloc),
|
||||
.boo => try boo.run(alloc),
|
||||
.@"new-window" => try new_window.run(alloc),
|
||||
.@"toggle-quick-terminal" => try toggle_quick_terminal.run(alloc),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -192,6 +197,7 @@ pub const Action = enum {
|
||||
.@"show-face" => show_face.Options,
|
||||
.boo => boo.Options,
|
||||
.@"new-window" => new_window.Options,
|
||||
.@"toggle-quick-terminal" => toggle_quick_terminal.Options,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
62
src/cli/toggle_quick_terminal.zig
Normal file
62
src/cli/toggle_quick_terminal.zig
Normal file
@@ -0,0 +1,62 @@
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Action = @import("../cli.zig").ghostty.Action;
|
||||
const apprt = @import("../apprt.zig");
|
||||
|
||||
pub const Options = struct {
|
||||
/// If set, connect to a custom instance of Ghostty.
|
||||
class: ?[:0]const u8 = null,
|
||||
|
||||
pub fn deinit(self: *Options) void {
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
/// Enables "-h" and "--help" to work.
|
||||
pub fn help(self: Options) !void {
|
||||
_ = self;
|
||||
return Action.help_error;
|
||||
}
|
||||
};
|
||||
|
||||
/// The `+toggle-quick-terminal` command will use native platform IPC to toggle
|
||||
/// the quick terminal in a running instance of Ghostty.
|
||||
///
|
||||
/// If the `--class` flag is not set, the command will try and connect to the
|
||||
/// default running Ghostty instance. Otherwise it will contact a Ghostty
|
||||
/// instance configured with the given `class`.
|
||||
///
|
||||
/// On GTK, D-Bus activation must be properly configured. Ghostty does not need
|
||||
/// to be running, as D-Bus will handle launching a new instance if it is not
|
||||
/// already running.
|
||||
///
|
||||
/// Only supported on GTK.
|
||||
///
|
||||
/// Flags:
|
||||
///
|
||||
/// * `--class=<class>`: If set, connect to a custom instance of Ghostty.
|
||||
/// The class must be a valid GTK application ID.
|
||||
///
|
||||
/// Available since: 1.3.0
|
||||
pub fn run(alloc: Allocator) !u8 {
|
||||
var buf: [256]u8 = undefined;
|
||||
var stderr_writer = std.fs.File.stderr().writer(&buf);
|
||||
const stderr = &stderr_writer.interface;
|
||||
|
||||
if (apprt.App.performIpc(
|
||||
alloc,
|
||||
.detect,
|
||||
.toggle_quick_terminal,
|
||||
{},
|
||||
) catch |err| switch (err) {
|
||||
error.IPCFailed => {
|
||||
return 1;
|
||||
},
|
||||
else => {
|
||||
try stderr.print("Sending the IPC failed: {}\n", .{err});
|
||||
return 1;
|
||||
},
|
||||
}) return 0;
|
||||
|
||||
try stderr.print("+toggle-quick-terminal is not supported on this platform.\n", .{});
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user