mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 01:06:08 +03:00
Merge pull request #172 from mitchellh/mrn/toggle-fullscreen
Toggle fullscreen on super/ctrl+return, only macOS for now
This commit is contained in:
@ -239,6 +239,7 @@ typedef void (*ghostty_runtime_new_split_cb)(void *, ghostty_split_direction_e);
|
|||||||
typedef void (*ghostty_runtime_close_surface_cb)(void *, bool);
|
typedef void (*ghostty_runtime_close_surface_cb)(void *, bool);
|
||||||
typedef void (*ghostty_runtime_focus_split_cb)(void *, ghostty_split_focus_direction_e);
|
typedef void (*ghostty_runtime_focus_split_cb)(void *, ghostty_split_focus_direction_e);
|
||||||
typedef void (*ghostty_runtime_goto_tab_cb)(void *, int32_t);
|
typedef void (*ghostty_runtime_goto_tab_cb)(void *, int32_t);
|
||||||
|
typedef void (*ghostty_runtime_toggle_fullscreen_cb)(void *);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *userdata;
|
void *userdata;
|
||||||
@ -251,6 +252,7 @@ typedef struct {
|
|||||||
ghostty_runtime_close_surface_cb close_surface_cb;
|
ghostty_runtime_close_surface_cb close_surface_cb;
|
||||||
ghostty_runtime_focus_split_cb focus_split_cb;
|
ghostty_runtime_focus_split_cb focus_split_cb;
|
||||||
ghostty_runtime_goto_tab_cb goto_tab_cb;
|
ghostty_runtime_goto_tab_cb goto_tab_cb;
|
||||||
|
ghostty_runtime_toggle_fullscreen_cb toggle_fullscreen_cb;
|
||||||
} ghostty_runtime_config_s;
|
} ghostty_runtime_config_s;
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
|
@ -28,6 +28,7 @@ struct ContentView: View {
|
|||||||
case .ready:
|
case .ready:
|
||||||
let center = NotificationCenter.default
|
let center = NotificationCenter.default
|
||||||
let gotoTab = center.publisher(for: Ghostty.Notification.ghosttyGotoTab)
|
let gotoTab = center.publisher(for: Ghostty.Notification.ghosttyGotoTab)
|
||||||
|
let toggleFullscreen = center.publisher(for: Ghostty.Notification.ghosttyToggleFullscreen)
|
||||||
|
|
||||||
let confirmQuitting = Binding<Bool>(get: {
|
let confirmQuitting = Binding<Bool>(get: {
|
||||||
self.appDelegate.confirmQuit && (self.window?.isKeyWindow ?? false)
|
self.appDelegate.confirmQuit && (self.window?.isKeyWindow ?? false)
|
||||||
@ -39,6 +40,7 @@ struct ContentView: View {
|
|||||||
.ghosttyApp(ghostty.app!)
|
.ghosttyApp(ghostty.app!)
|
||||||
.background(WindowAccessor(window: $window))
|
.background(WindowAccessor(window: $window))
|
||||||
.onReceive(gotoTab) { onGotoTab(notification: $0) }
|
.onReceive(gotoTab) { onGotoTab(notification: $0) }
|
||||||
|
.onReceive(toggleFullscreen) { onToggleFullscreen(notification: $0) }
|
||||||
.confirmationDialog(
|
.confirmationDialog(
|
||||||
"Quit Ghostty?",
|
"Quit Ghostty?",
|
||||||
isPresented: confirmQuitting) {
|
isPresented: confirmQuitting) {
|
||||||
@ -84,4 +86,14 @@ struct ContentView: View {
|
|||||||
let targetWindow = tabbedWindows[adjustedIndex]
|
let targetWindow = tabbedWindows[adjustedIndex]
|
||||||
targetWindow.makeKeyAndOrderFront(nil)
|
targetWindow.makeKeyAndOrderFront(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func onToggleFullscreen(notification: SwiftUI.Notification) {
|
||||||
|
// Just like in `onGotoTab`, we might receive this multiple times. But
|
||||||
|
// it's fine, because `toggleFullscreen` should only apply to the
|
||||||
|
// currently focused window.
|
||||||
|
guard let window = self.window else { return }
|
||||||
|
guard window.isKeyWindow else { return }
|
||||||
|
|
||||||
|
window.toggleFullScreen(nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,8 @@ extension Ghostty {
|
|||||||
new_split_cb: { userdata, direction in AppState.newSplit(userdata, direction: direction) },
|
new_split_cb: { userdata, direction in AppState.newSplit(userdata, direction: direction) },
|
||||||
close_surface_cb: { userdata, processAlive in AppState.closeSurface(userdata, processAlive: processAlive) },
|
close_surface_cb: { userdata, processAlive in AppState.closeSurface(userdata, processAlive: processAlive) },
|
||||||
focus_split_cb: { userdata, direction in AppState.focusSplit(userdata, direction: direction) },
|
focus_split_cb: { userdata, direction in AppState.focusSplit(userdata, direction: direction) },
|
||||||
goto_tab_cb: { userdata, n in AppState.gotoTab(userdata, n: n) }
|
goto_tab_cb: { userdata, n in AppState.gotoTab(userdata, n: n) },
|
||||||
|
toggle_fullscreen_cb: { userdata in AppState.toggleFullscreen(userdata) }
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create the ghostty app.
|
// Create the ghostty app.
|
||||||
@ -218,6 +219,15 @@ extension Ghostty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func toggleFullscreen(_ userdata: UnsafeMutableRawPointer?) {
|
||||||
|
guard let surface = self.surfaceUserdata(from: userdata) else { return }
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: Notification.ghosttyToggleFullscreen,
|
||||||
|
object: surface,
|
||||||
|
userInfo: [:]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the GhosttyState from the given userdata value.
|
/// Returns the GhosttyState from the given userdata value.
|
||||||
static private func appState(fromSurface userdata: UnsafeMutableRawPointer?) -> AppState? {
|
static private func appState(fromSurface userdata: UnsafeMutableRawPointer?) -> AppState? {
|
||||||
let surfaceView = Unmanaged<SurfaceView>.fromOpaque(userdata!).takeUnretainedValue()
|
let surfaceView = Unmanaged<SurfaceView>.fromOpaque(userdata!).takeUnretainedValue()
|
||||||
|
@ -78,6 +78,9 @@ extension Ghostty.Notification {
|
|||||||
/// Goto tab. Has tab index in the userinfo.
|
/// Goto tab. Has tab index in the userinfo.
|
||||||
static let ghosttyGotoTab = Notification.Name("com.mitchellh.ghostty.gotoTab")
|
static let ghosttyGotoTab = Notification.Name("com.mitchellh.ghostty.gotoTab")
|
||||||
static let GotoTabKey = ghosttyGotoTab.rawValue
|
static let GotoTabKey = ghosttyGotoTab.rawValue
|
||||||
|
|
||||||
|
/// Toggle fullscreen of current window
|
||||||
|
static let ghosttyToggleFullscreen = Notification.Name("com.mitchellh.ghostty.toggleFullscreen")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the input enum hashable.
|
// Make the input enum hashable.
|
||||||
|
@ -1135,6 +1135,12 @@ pub fn keyCallback(
|
|||||||
} else log.warn("runtime doesn't implement gotoSplit", .{});
|
} else log.warn("runtime doesn't implement gotoSplit", .{});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.toggle_fullscreen => {
|
||||||
|
if (@hasDecl(apprt.Surface, "toggleFullscreen")) {
|
||||||
|
self.rt_surface.toggleFullscreen();
|
||||||
|
} else log.warn("runtime doesn't implement toggleFullscreen", .{});
|
||||||
|
},
|
||||||
|
|
||||||
.close_surface => self.close(),
|
.close_surface => self.close(),
|
||||||
|
|
||||||
.close_window => {
|
.close_window => {
|
||||||
|
@ -64,6 +64,9 @@ pub const App = struct {
|
|||||||
|
|
||||||
/// Goto tab
|
/// Goto tab
|
||||||
goto_tab: ?*const fn (SurfaceUD, usize) callconv(.C) void = null,
|
goto_tab: ?*const fn (SurfaceUD, usize) callconv(.C) void = null,
|
||||||
|
|
||||||
|
/// Toggle fullscreen for current window.
|
||||||
|
toggle_fullscreen: ?*const fn (SurfaceUD) callconv(.C) void = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
core_app: *CoreApp,
|
core_app: *CoreApp,
|
||||||
@ -371,6 +374,15 @@ pub const Surface = struct {
|
|||||||
func(self.opts.userdata, n);
|
func(self.opts.userdata, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn toggleFullscreen(self: *Surface) void {
|
||||||
|
const func = self.app.opts.toggle_fullscreen orelse {
|
||||||
|
log.info("runtime embedder does not toggle_fullscreen", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
func(self.opts.userdata);
|
||||||
|
}
|
||||||
|
|
||||||
/// The cursor position from the host directly is in screen coordinates but
|
/// The cursor position from the host directly is in screen coordinates but
|
||||||
/// all our interface works in pixels.
|
/// all our interface works in pixels.
|
||||||
fn cursorPosToPixels(self: *const Surface, pos: apprt.CursorPos) !apprt.CursorPos {
|
fn cursorPosToPixels(self: *const Surface, pos: apprt.CursorPos) !apprt.CursorPos {
|
||||||
|
@ -441,6 +441,13 @@ pub const Config = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Toggle fullscreen
|
||||||
|
try result.keybind.set.put(
|
||||||
|
alloc,
|
||||||
|
.{ .key = .enter, .mods = ctrlOrSuper(.{}) },
|
||||||
|
.{ .toggle_fullscreen = {} },
|
||||||
|
);
|
||||||
|
|
||||||
// Mac-specific keyboard bindings.
|
// Mac-specific keyboard bindings.
|
||||||
if (comptime builtin.target.isDarwin()) {
|
if (comptime builtin.target.isDarwin()) {
|
||||||
try result.keybind.set.put(
|
try result.keybind.set.put(
|
||||||
|
@ -207,6 +207,9 @@ pub const Action = union(enum) {
|
|||||||
/// Close the window, regardless of how many tabs or splits there may be.
|
/// Close the window, regardless of how many tabs or splits there may be.
|
||||||
close_window: void,
|
close_window: void,
|
||||||
|
|
||||||
|
/// Toggle fullscreen mode of window.
|
||||||
|
toggle_fullscreen: void,
|
||||||
|
|
||||||
/// Quit ghostty
|
/// Quit ghostty
|
||||||
quit: void,
|
quit: void,
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user