mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
Merge pull request #835 from Raiden1411/feat/glfw
glfw: add `fullscreen` and `toggleFullscreen` support
This commit is contained in:
@ -144,6 +144,52 @@ pub const App = struct {
|
||||
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()) {
|
||||
win.setMonitor(
|
||||
null,
|
||||
@intCast(surface.monitor_dims.position_x),
|
||||
@intCast(surface.monitor_dims.position_y),
|
||||
surface.monitor_dims.width,
|
||||
surface.monitor_dims.height,
|
||||
0,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
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 video_mode = monitor.getVideoMode() orelse {
|
||||
log.warn("failed to get video mode. 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.monitor_dims = .{
|
||||
.width = size.width,
|
||||
.height = size.height,
|
||||
.position_x = position.x,
|
||||
.position_y = position.y,
|
||||
};
|
||||
|
||||
win.setMonitor(monitor, 0, 0, video_mode.getWidth(), video_mode.getHeight(), 0);
|
||||
}
|
||||
|
||||
/// Create a new window for the app.
|
||||
pub fn newWindow(self: *App, parent_: ?*CoreSurface) !void {
|
||||
_ = try self.newSurface(parent_);
|
||||
@ -267,6 +313,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
|
||||
/// is always a window because that is the only abstraction that glfw exposes.
|
||||
///
|
||||
@ -297,17 +352,21 @@ pub const Surface = struct {
|
||||
/// (GLFW guarantees that charCallback is called after keyCallback).
|
||||
key_event: ?input.KeyEvent = null,
|
||||
|
||||
/// The monitor dimensions so we can toggle fullscreen on and off.
|
||||
monitor_dims: MonitorDimensions,
|
||||
|
||||
pub const Options = struct {};
|
||||
|
||||
/// Initialize the surface into the given self pointer. This gives a
|
||||
/// stable pointer to the destination that can be used for callbacks.
|
||||
pub fn init(self: *Surface, app: *App) !void {
|
||||
|
||||
// Create our window
|
||||
const win = glfw.Window.create(
|
||||
640,
|
||||
480,
|
||||
"ghostty",
|
||||
null,
|
||||
if (app.config.fullscreen) glfw.Monitor.getPrimary() else null,
|
||||
null,
|
||||
Renderer.glfwWindowHints(&app.config),
|
||||
) orelse return glfw.mustGetErrorCode();
|
||||
@ -320,8 +379,8 @@ pub const Surface = struct {
|
||||
log.warn("window had null monitor, getting primary monitor", .{});
|
||||
break :monitor glfw.Monitor.getPrimary().?;
|
||||
};
|
||||
const physical_size = monitor.getPhysicalSize();
|
||||
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_y_dpi = @as(f32, @floatFromInt(video_mode.getHeight())) / (@as(f32, @floatFromInt(physical_size.height_mm)) / 25.4);
|
||||
log.debug("physical dpi x={} y={}", .{
|
||||
@ -355,12 +414,24 @@ pub const Surface = struct {
|
||||
win.setMouseButtonCallback(mouseButtonCallback);
|
||||
win.setDropCallback(dropCallback);
|
||||
|
||||
const dimensions: MonitorDimensions = dimensions: {
|
||||
const pos = win.getPos();
|
||||
const size = win.getFramebufferSize();
|
||||
break :dimensions .{
|
||||
.width = size.width,
|
||||
.height = size.height,
|
||||
.position_x = pos.x,
|
||||
.position_y = pos.y,
|
||||
};
|
||||
};
|
||||
|
||||
// Build our result
|
||||
self.* = .{
|
||||
.app = app,
|
||||
.window = win,
|
||||
.cursor = null,
|
||||
.core_surface = undefined,
|
||||
.monitor_dims = dimensions,
|
||||
};
|
||||
errdefer self.* = undefined;
|
||||
|
||||
@ -447,6 +518,15 @@ pub const Surface = struct {
|
||||
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.
|
||||
pub fn close(self: *Surface, processActive: bool) void {
|
||||
_ = processActive;
|
||||
|
Reference in New Issue
Block a user