mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
Add config setting to turn non-native fullscreen on or off
This commit is contained in:

committed by
Mitchell Hashimoto

parent
850bf3e945
commit
b56ffa6285
@ -239,7 +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 void (*ghostty_runtime_toggle_fullscreen_cb)(void *, bool);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *userdata;
|
void *userdata;
|
||||||
|
@ -110,8 +110,12 @@ struct ContentView: View {
|
|||||||
// currently focused window.
|
// currently focused window.
|
||||||
guard let window = self.window else { return }
|
guard let window = self.window else { return }
|
||||||
guard window.isKeyWindow else { return }
|
guard window.isKeyWindow else { return }
|
||||||
|
|
||||||
self.fsHandler.toggleFullscreen(window: window)
|
// Check whether we use non-native fullscreen
|
||||||
|
guard let useNonNativeFullscreenAny = notification.userInfo?[Ghostty.Notification.NonNativeFullscreenKey] else { return }
|
||||||
|
guard let useNonNativeFullscreen = useNonNativeFullscreenAny as? Bool else { return }
|
||||||
|
|
||||||
|
self.fsHandler.toggleFullscreen(window: window, nonNativeFullscreen: useNonNativeFullscreen)
|
||||||
// After toggling fullscreen we need to focus the terminal again.
|
// After toggling fullscreen we need to focus the terminal again.
|
||||||
self.focused = true
|
self.focused = true
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,27 @@ class FullScreenHandler {
|
|||||||
var previousStyleMask: NSWindow.StyleMask?
|
var previousStyleMask: NSWindow.StyleMask?
|
||||||
var isInFullscreen: Bool = false
|
var isInFullscreen: Bool = false
|
||||||
|
|
||||||
func toggleFullscreen(window: NSWindow) {
|
// We keep track of whether we entered non-native fullscreen in case
|
||||||
|
// a user goes to fullscreen, changes the config to disable non-native fullscreen
|
||||||
|
// and then wants to toggle it off
|
||||||
|
var isInNonNativeFullscreen: Bool = false
|
||||||
|
|
||||||
|
func toggleFullscreen(window: NSWindow, nonNativeFullscreen: Bool) {
|
||||||
if isInFullscreen {
|
if isInFullscreen {
|
||||||
leaveFullscreen(window: window)
|
if nonNativeFullscreen || isInNonNativeFullscreen {
|
||||||
|
leaveFullscreen(window: window)
|
||||||
|
isInNonNativeFullscreen = false
|
||||||
|
} else {
|
||||||
|
window.toggleFullScreen(nil)
|
||||||
|
}
|
||||||
isInFullscreen = false
|
isInFullscreen = false
|
||||||
} else {
|
} else {
|
||||||
enterFullscreen(window: window)
|
if nonNativeFullscreen {
|
||||||
|
enterFullscreen(window: window)
|
||||||
|
isInNonNativeFullscreen = true
|
||||||
|
} else {
|
||||||
|
window.toggleFullScreen(nil)
|
||||||
|
}
|
||||||
isInFullscreen = true
|
isInFullscreen = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ extension Ghostty {
|
|||||||
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) }
|
toggle_fullscreen_cb: { userdata, nonNativeFullscreen in AppState.toggleFullscreen(userdata, useNonNativeFullscreen: nonNativeFullscreen) }
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create the ghostty app.
|
// Create the ghostty app.
|
||||||
@ -219,12 +219,15 @@ extension Ghostty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func toggleFullscreen(_ userdata: UnsafeMutableRawPointer?) {
|
static func toggleFullscreen(_ userdata: UnsafeMutableRawPointer?, useNonNativeFullscreen: Bool) {
|
||||||
|
// togo: use non-native fullscreen
|
||||||
guard let surface = self.surfaceUserdata(from: userdata) else { return }
|
guard let surface = self.surfaceUserdata(from: userdata) else { return }
|
||||||
NotificationCenter.default.post(
|
NotificationCenter.default.post(
|
||||||
name: Notification.ghosttyToggleFullscreen,
|
name: Notification.ghosttyToggleFullscreen,
|
||||||
object: surface,
|
object: surface,
|
||||||
userInfo: [:]
|
userInfo: [
|
||||||
|
Notification.NonNativeFullscreenKey: useNonNativeFullscreen,
|
||||||
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ extension Ghostty.Notification {
|
|||||||
|
|
||||||
/// Toggle fullscreen of current window
|
/// Toggle fullscreen of current window
|
||||||
static let ghosttyToggleFullscreen = Notification.Name("com.mitchellh.ghostty.toggleFullscreen")
|
static let ghosttyToggleFullscreen = Notification.Name("com.mitchellh.ghostty.toggleFullscreen")
|
||||||
|
static let NonNativeFullscreenKey = ghosttyToggleFullscreen.rawValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the input enum hashable.
|
// Make the input enum hashable.
|
||||||
|
@ -146,6 +146,7 @@ const DerivedConfig = struct {
|
|||||||
clipboard_trim_trailing_spaces: bool,
|
clipboard_trim_trailing_spaces: bool,
|
||||||
confirm_close_surface: bool,
|
confirm_close_surface: bool,
|
||||||
mouse_interval: u64,
|
mouse_interval: u64,
|
||||||
|
macos_non_native_fullscreen: bool,
|
||||||
|
|
||||||
pub fn init(alloc_gpa: Allocator, config: *const configpkg.Config) !DerivedConfig {
|
pub fn init(alloc_gpa: Allocator, config: *const configpkg.Config) !DerivedConfig {
|
||||||
var arena = ArenaAllocator.init(alloc_gpa);
|
var arena = ArenaAllocator.init(alloc_gpa);
|
||||||
@ -160,6 +161,7 @@ const DerivedConfig = struct {
|
|||||||
.clipboard_trim_trailing_spaces = config.@"clipboard-trim-trailing-spaces",
|
.clipboard_trim_trailing_spaces = config.@"clipboard-trim-trailing-spaces",
|
||||||
.confirm_close_surface = config.@"confirm-close-surface",
|
.confirm_close_surface = config.@"confirm-close-surface",
|
||||||
.mouse_interval = config.@"click-repeat-interval" * 1_000_000, // 500ms
|
.mouse_interval = config.@"click-repeat-interval" * 1_000_000, // 500ms
|
||||||
|
.macos_non_native_fullscreen = config.@"macos-non-native-fullscreen",
|
||||||
|
|
||||||
// Assignments happen sequentially so we have to do this last
|
// Assignments happen sequentially so we have to do this last
|
||||||
// so that the memory is captured from allocs above.
|
// so that the memory is captured from allocs above.
|
||||||
@ -1213,7 +1215,7 @@ pub fn keyCallback(
|
|||||||
|
|
||||||
.toggle_fullscreen => {
|
.toggle_fullscreen => {
|
||||||
if (@hasDecl(apprt.Surface, "toggleFullscreen")) {
|
if (@hasDecl(apprt.Surface, "toggleFullscreen")) {
|
||||||
self.rt_surface.toggleFullscreen();
|
self.rt_surface.toggleFullscreen(self.config.macos_non_native_fullscreen);
|
||||||
} else log.warn("runtime doesn't implement toggleFullscreen", .{});
|
} else log.warn("runtime doesn't implement toggleFullscreen", .{});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ pub const App = struct {
|
|||||||
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 for current window.
|
||||||
toggle_fullscreen: ?*const fn (SurfaceUD) callconv(.C) void = null,
|
toggle_fullscreen: ?*const fn (SurfaceUD, bool) callconv(.C) void = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
core_app: *CoreApp,
|
core_app: *CoreApp,
|
||||||
@ -374,13 +374,13 @@ pub const Surface = struct {
|
|||||||
func(self.opts.userdata, n);
|
func(self.opts.userdata, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggleFullscreen(self: *Surface) void {
|
pub fn toggleFullscreen(self: *Surface, nonNativeFullscreen: bool) void {
|
||||||
const func = self.app.opts.toggle_fullscreen orelse {
|
const func = self.app.opts.toggle_fullscreen orelse {
|
||||||
log.info("runtime embedder does not toggle_fullscreen", .{});
|
log.info("runtime embedder does not toggle_fullscreen", .{});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
func(self.opts.userdata);
|
func(self.opts.userdata, nonNativeFullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The cursor position from the host directly is in screen coordinates but
|
/// The cursor position from the host directly is in screen coordinates but
|
||||||
|
@ -483,7 +483,7 @@ const Window = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Toggle fullscreen for this window.
|
/// Toggle fullscreen for this window.
|
||||||
fn toggleFullscreen(self: *Window) void {
|
fn toggleFullscreen(self: *Window, _: bool) void {
|
||||||
const is_fullscreen = c.gtk_window_is_fullscreen(self.window);
|
const is_fullscreen = c.gtk_window_is_fullscreen(self.window);
|
||||||
if (is_fullscreen == 0) {
|
if (is_fullscreen == 0) {
|
||||||
c.gtk_window_fullscreen(self.window);
|
c.gtk_window_fullscreen(self.window);
|
||||||
|
@ -221,6 +221,12 @@ pub const Config = struct {
|
|||||||
/// The default value is "detect".
|
/// The default value is "detect".
|
||||||
@"shell-integration": ShellIntegration = .detect,
|
@"shell-integration": ShellIntegration = .detect,
|
||||||
|
|
||||||
|
/// If true, fullscreen mode on macOS will not use the native fullscreen,
|
||||||
|
/// but make the window fullscreen without animations and using a new space.
|
||||||
|
/// That's faster than the native fullscreen mode since it doesn't use
|
||||||
|
/// animations.
|
||||||
|
@"macos-non-native-fullscreen": bool = false,
|
||||||
|
|
||||||
/// This is set by the CLI parser for deinit.
|
/// This is set by the CLI parser for deinit.
|
||||||
_arena: ?ArenaAllocator = null,
|
_arena: ?ArenaAllocator = null,
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user