feat: fullscreen and toggleFullscreen support

This commit is contained in:
Raiden1411
2023-11-07 17:58:00 +00:00
parent 4e3ab4879d
commit fbe2b7c267

View File

@ -144,6 +144,38 @@ pub const App = struct {
return &self.config; return &self.config;
} }
/// Toggle the window to fullscreen mode.
pub fn toggleFullscreen(self: *App, surface: *Surface) void {
_ = self;
const win = surface.window;
if (!surface.isFullscreen()) {
const monitor = win.getMonitor() orelse monitor: {
log.warn("window had null monitor, getting primary monitor", .{});
break :monitor glfw.Monitor.getPrimary() orelse {
log.warn("window could not get any monitor. Will not perform action", .{});
return;
};
};
const position = win.getPos();
const size = surface.getSize() catch {
log.warn("Failed to get window size. Will not perform fullscreen action", .{});
return;
};
surface.window_dimensions = .{
.width = size.width,
.height = size.height,
.position_x = position.x,
.position_y = position.y,
};
win.setMonitor(monitor, 0, 0, surface.window_dimensions.width, surface.window_dimensions.height, 0);
} else {
win.setMonitor(null, @as(i32, @intCast(surface.window_dimensions.position_x)), @as(i32, @intCast(surface.window_dimensions.position_y)), surface.window_dimensions.width, surface.window_dimensions.height, 0);
}
}
/// Create a new window for the app. /// Create a new window for the app.
pub fn newWindow(self: *App, parent_: ?*CoreSurface) !void { pub fn newWindow(self: *App, parent_: ?*CoreSurface) !void {
_ = try self.newSurface(parent_); _ = try self.newSurface(parent_);
@ -267,6 +299,15 @@ pub const App = struct {
}; };
}; };
/// These are used to keep track of the original monitor values so that we can safely
/// toggle on and off of fullscreen.
const MonitorDimensions = struct {
width: u32,
height: u32,
position_x: i64,
position_y: i64,
};
/// Surface represents the drawable surface for glfw. In glfw, a surface /// Surface represents the drawable surface for glfw. In glfw, a surface
/// is always a window because that is the only abstraction that glfw exposes. /// is always a window because that is the only abstraction that glfw exposes.
/// ///
@ -297,17 +338,21 @@ pub const Surface = struct {
/// (GLFW guarantees that charCallback is called after keyCallback). /// (GLFW guarantees that charCallback is called after keyCallback).
key_event: ?input.KeyEvent = null, key_event: ?input.KeyEvent = null,
window_dimensions: MonitorDimensions,
pub const Options = struct {}; pub const Options = struct {};
/// Initialize the surface into the given self pointer. This gives a /// Initialize the surface into the given self pointer. This gives a
/// stable pointer to the destination that can be used for callbacks. /// stable pointer to the destination that can be used for callbacks.
pub fn init(self: *Surface, app: *App) !void { pub fn init(self: *Surface, app: *App) !void {
const fullscreen = if (app.config.fullscreen) glfw.Monitor.getPrimary().? else null;
// Create our window // Create our window
const win = glfw.Window.create( const win = glfw.Window.create(
640, 640,
480, 480,
"ghostty", "ghostty",
null, fullscreen,
null, null,
Renderer.glfwWindowHints(&app.config), Renderer.glfwWindowHints(&app.config),
) orelse return glfw.mustGetErrorCode(); ) orelse return glfw.mustGetErrorCode();
@ -320,8 +365,8 @@ pub const Surface = struct {
log.warn("window had null monitor, getting primary monitor", .{}); log.warn("window had null monitor, getting primary monitor", .{});
break :monitor glfw.Monitor.getPrimary().?; break :monitor glfw.Monitor.getPrimary().?;
}; };
const physical_size = monitor.getPhysicalSize();
const video_mode = monitor.getVideoMode() orelse return glfw.mustGetErrorCode(); const video_mode = monitor.getVideoMode() orelse return glfw.mustGetErrorCode();
const physical_size = monitor.getPhysicalSize();
const physical_x_dpi = @as(f32, @floatFromInt(video_mode.getWidth())) / (@as(f32, @floatFromInt(physical_size.width_mm)) / 25.4); const physical_x_dpi = @as(f32, @floatFromInt(video_mode.getWidth())) / (@as(f32, @floatFromInt(physical_size.width_mm)) / 25.4);
const physical_y_dpi = @as(f32, @floatFromInt(video_mode.getHeight())) / (@as(f32, @floatFromInt(physical_size.height_mm)) / 25.4); const physical_y_dpi = @as(f32, @floatFromInt(video_mode.getHeight())) / (@as(f32, @floatFromInt(physical_size.height_mm)) / 25.4);
log.debug("physical dpi x={} y={}", .{ log.debug("physical dpi x={} y={}", .{
@ -361,6 +406,7 @@ pub const Surface = struct {
.window = win, .window = win,
.cursor = null, .cursor = null,
.core_surface = undefined, .core_surface = undefined,
.window_dimensions = undefined,
}; };
errdefer self.* = undefined; errdefer self.* = undefined;
@ -447,6 +493,15 @@ pub const Surface = struct {
try self.app.newTab(&self.core_surface); try self.app.newTab(&self.core_surface);
} }
/// Checks if the glfw window is in fullscreen.
pub fn isFullscreen(self: *Surface) bool {
return self.window.getMonitor() != null;
}
pub fn toggleFullscreen(self: *Surface, _: Config.NonNativeFullscreen) void {
self.app.toggleFullscreen(self);
}
/// Close this surface. /// Close this surface.
pub fn close(self: *Surface, processActive: bool) void { pub fn close(self: *Surface, processActive: bool) void {
_ = processActive; _ = processActive;