mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
terminal: OSC7 with empty URL resets the pwd to nil
When an empty string is given to OSC7, the pwd is reset to nil (as if the terminal never received a pwd report to begin with). This is analogous to how OSC0/2 reset the title to nil when given an empty string. This is practically useful for macOS because it allows our proxy icon to also be reset instead of being stuck on the last known path. This breaks from any known terminal behavior. As far as I can find, this is totally unspecified so we're somewhat free to do what we want. I don't think any terminal programs depend on this behavior, so I think it's safe to change it.
This commit is contained in:
@ -641,7 +641,7 @@ pub const Parser = struct {
|
||||
.@"7" => switch (c) {
|
||||
';' => {
|
||||
self.command = .{ .report_pwd = .{ .value = "" } };
|
||||
|
||||
self.complete = true;
|
||||
self.state = .string;
|
||||
self.temp_state = .{ .str = &self.command.report_pwd.value };
|
||||
self.buf_start = self.buf_idx;
|
||||
@ -1382,6 +1382,18 @@ test "OSC: report pwd" {
|
||||
try testing.expect(std.mem.eql(u8, "file:///tmp/example", cmd.report_pwd.value));
|
||||
}
|
||||
|
||||
test "OSC: report pwd empty" {
|
||||
const testing = std.testing;
|
||||
|
||||
var p: Parser = .{};
|
||||
|
||||
const input = "7;";
|
||||
for (input) |ch| p.next(ch);
|
||||
const cmd = p.end(null).?;
|
||||
try testing.expect(cmd == .report_pwd);
|
||||
try testing.expect(std.mem.eql(u8, "", cmd.report_pwd.value));
|
||||
}
|
||||
|
||||
test "OSC: pointer cursor" {
|
||||
const testing = std.testing;
|
||||
|
||||
@ -1395,17 +1407,6 @@ test "OSC: pointer cursor" {
|
||||
try testing.expect(std.mem.eql(u8, "pointer", cmd.mouse_shape.value));
|
||||
}
|
||||
|
||||
test "OSC: report pwd empty" {
|
||||
const testing = std.testing;
|
||||
|
||||
var p: Parser = .{};
|
||||
|
||||
const input = "7;";
|
||||
for (input) |ch| p.next(ch);
|
||||
|
||||
try testing.expect(p.end(null) == null);
|
||||
}
|
||||
|
||||
test "OSC: longer than buffer" {
|
||||
const testing = std.testing;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const xev = @import("xev");
|
||||
const apprt = @import("../apprt.zig");
|
||||
@ -1048,6 +1049,28 @@ pub const StreamHandler = struct {
|
||||
}
|
||||
|
||||
pub fn reportPwd(self: *StreamHandler, url: []const u8) !void {
|
||||
// Special handling for the empty URL. We treat the empty URL
|
||||
// as resetting the pwd as if we never saw a pwd. I can't find any
|
||||
// other terminal that does this but it seems like a reasonable
|
||||
// behavior that enables some useful features. For example, the macOS
|
||||
// proxy icon can be hidden when a program reports it doesn't know
|
||||
// the pwd rather than showing a stale pwd.
|
||||
if (url.len == 0) {
|
||||
// Blank value can never fail because no allocs happen.
|
||||
self.terminal.setPwd("") catch unreachable;
|
||||
|
||||
// If we haven't seen a title, we're using the pwd as our title.
|
||||
// Set it to blank which will reset our title behavior.
|
||||
if (!self.seen_title) {
|
||||
try self.changeWindowTitle("");
|
||||
assert(!self.seen_title);
|
||||
}
|
||||
|
||||
// Report the change.
|
||||
self.surfaceMessageWriter(.{ .pwd_change = .{ .stable = "" } });
|
||||
return;
|
||||
}
|
||||
|
||||
if (builtin.os.tag == .windows) {
|
||||
log.warn("reportPwd unimplemented on windows", .{});
|
||||
return;
|
||||
|
Reference in New Issue
Block a user