apprt/gtk-ng: initialize window protocol
parent
469001b7f6
commit
c7eee9ee7a
|
|
@ -15,6 +15,7 @@ const ext = @import("../ext.zig");
|
||||||
const gtk_version = @import("../gtk_version.zig");
|
const gtk_version = @import("../gtk_version.zig");
|
||||||
const adw_version = @import("../adw_version.zig");
|
const adw_version = @import("../adw_version.zig");
|
||||||
const gresource = @import("../build/gresource.zig");
|
const gresource = @import("../build/gresource.zig");
|
||||||
|
const winprotopkg = @import("../winproto.zig");
|
||||||
const Common = @import("../class.zig").Common;
|
const Common = @import("../class.zig").Common;
|
||||||
const Config = @import("config.zig").Config;
|
const Config = @import("config.zig").Config;
|
||||||
const Application = @import("application.zig").Application;
|
const Application = @import("application.zig").Application;
|
||||||
|
|
@ -131,6 +132,26 @@ pub const Window = extern struct {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const @"quick-terminal" = struct {
|
||||||
|
pub const name = "quick-terminal";
|
||||||
|
const impl = gobject.ext.defineProperty(
|
||||||
|
name,
|
||||||
|
Self,
|
||||||
|
bool,
|
||||||
|
.{
|
||||||
|
.nick = "Quick Terminal",
|
||||||
|
.blurb = "Whether this window behaves like a quick terminal.",
|
||||||
|
.default = true,
|
||||||
|
.accessor = gobject.ext.privateFieldAccessor(
|
||||||
|
Self,
|
||||||
|
Private,
|
||||||
|
&Private.offset,
|
||||||
|
"quick_terminal",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
pub const @"tabs-autohide" = struct {
|
pub const @"tabs-autohide" = struct {
|
||||||
pub const name = "tabs-autohide";
|
pub const name = "tabs-autohide";
|
||||||
const impl = gobject.ext.defineProperty(
|
const impl = gobject.ext.defineProperty(
|
||||||
|
|
@ -205,12 +226,19 @@ pub const Window = extern struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Private = struct {
|
const Private = struct {
|
||||||
|
/// Whether this window is a quick terminal. If it is then it
|
||||||
|
/// behaves slightly differently under certain scenarios.
|
||||||
|
quick_terminal: bool = false,
|
||||||
|
|
||||||
/// Binding group for our active tab.
|
/// Binding group for our active tab.
|
||||||
tab_bindings: *gobject.BindingGroup,
|
tab_bindings: *gobject.BindingGroup,
|
||||||
|
|
||||||
/// The configuration that this surface is using.
|
/// The configuration that this surface is using.
|
||||||
config: ?*Config = null,
|
config: ?*Config = null,
|
||||||
|
|
||||||
|
/// State and logic for windowing protocol for a window.
|
||||||
|
winproto: winprotopkg.Window,
|
||||||
|
|
||||||
/// Kind of hacky to have this but this lets us know if we've
|
/// Kind of hacky to have this but this lets us know if we've
|
||||||
/// initialized any single surface yet. We need this because we
|
/// initialized any single surface yet. We need this because we
|
||||||
/// gate default size on this so that we don't resize the window
|
/// gate default size on this so that we don't resize the window
|
||||||
|
|
@ -253,6 +281,10 @@ pub const Window = extern struct {
|
||||||
priv.config = app.getConfig();
|
priv.config = app.getConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We initialize our windowing protocol to none because we can't
|
||||||
|
// actually initialize this until we get realized.
|
||||||
|
priv.winproto = .none;
|
||||||
|
|
||||||
// Add our dev CSS class if we're in debug mode.
|
// Add our dev CSS class if we're in debug mode.
|
||||||
if (comptime build_config.is_debug) {
|
if (comptime build_config.is_debug) {
|
||||||
self.as(gtk.Widget).addCssClass("devel");
|
self.as(gtk.Widget).addCssClass("devel");
|
||||||
|
|
@ -535,6 +567,11 @@ pub const Window = extern struct {
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Properties
|
// Properties
|
||||||
|
|
||||||
|
/// Whether this terminal is a quick terminal or not.
|
||||||
|
pub fn isQuickTerminal(self: *Self) bool {
|
||||||
|
return self.private().quick_terminal;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the currently active surface. See the "active-surface" property.
|
/// Get the currently active surface. See the "active-surface" property.
|
||||||
/// This does not ref the value.
|
/// This does not ref the value.
|
||||||
fn getActiveSurface(self: *Self) ?*Surface {
|
fn getActiveSurface(self: *Self) ?*Surface {
|
||||||
|
|
@ -542,6 +579,12 @@ pub const Window = extern struct {
|
||||||
return tab.getActiveSurface();
|
return tab.getActiveSurface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the configuration for this window. The reference count
|
||||||
|
/// is not increased.
|
||||||
|
pub fn getConfig(self: *Self) ?*Config {
|
||||||
|
return self.private().config;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the currently selected tab as a Tab object.
|
/// Get the currently selected tab as a Tab object.
|
||||||
fn getSelectedTab(self: *Self) ?*Tab {
|
fn getSelectedTab(self: *Self) ?*Tab {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
|
|
@ -731,6 +774,7 @@ pub const Window = extern struct {
|
||||||
fn finalize(self: *Self) callconv(.C) void {
|
fn finalize(self: *Self) callconv(.C) void {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
priv.tab_bindings.unref();
|
priv.tab_bindings.unref();
|
||||||
|
priv.winproto.deinit(Application.default().allocator());
|
||||||
|
|
||||||
gobject.Object.virtual_methods.finalize.call(
|
gobject.Object.virtual_methods.finalize.call(
|
||||||
Class.parent,
|
Class.parent,
|
||||||
|
|
@ -741,6 +785,26 @@ pub const Window = extern struct {
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Signal handlers
|
// Signal handlers
|
||||||
|
|
||||||
|
fn windowRealize(_: *gtk.Widget, self: *Window) callconv(.c) void {
|
||||||
|
const app = Application.default();
|
||||||
|
|
||||||
|
// Initialize our window protocol logic
|
||||||
|
if (winprotopkg.Window.init(
|
||||||
|
app.allocator(),
|
||||||
|
app.winproto(),
|
||||||
|
self,
|
||||||
|
)) |wp| {
|
||||||
|
self.private().winproto = wp;
|
||||||
|
} else |err| {
|
||||||
|
log.warn("failed to initialize window protocol error={}", .{err});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When we are realized we always setup our appearance since this
|
||||||
|
// calls some winproto functions.
|
||||||
|
self.syncAppearance();
|
||||||
|
}
|
||||||
|
|
||||||
fn btnNewTab(_: *adw.SplitButton, self: *Self) callconv(.c) void {
|
fn btnNewTab(_: *adw.SplitButton, self: *Self) callconv(.c) void {
|
||||||
self.performBindingAction(.new_tab);
|
self.performBindingAction(.new_tab);
|
||||||
}
|
}
|
||||||
|
|
@ -1376,6 +1440,7 @@ pub const Window = extern struct {
|
||||||
class.bindTemplateChildPrivate("toast_overlay", .{});
|
class.bindTemplateChildPrivate("toast_overlay", .{});
|
||||||
|
|
||||||
// Template Callbacks
|
// Template Callbacks
|
||||||
|
class.bindTemplateCallback("realize", &windowRealize);
|
||||||
class.bindTemplateCallback("new_tab", &btnNewTab);
|
class.bindTemplateCallback("new_tab", &btnNewTab);
|
||||||
class.bindTemplateCallback("overview_create_tab", &tabOverviewCreateTab);
|
class.bindTemplateCallback("overview_create_tab", &tabOverviewCreateTab);
|
||||||
class.bindTemplateCallback("overview_notify_open", &tabOverviewOpen);
|
class.bindTemplateCallback("overview_notify_open", &tabOverviewOpen);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ template $GhosttyWindow: Adw.ApplicationWindow {
|
||||||
]
|
]
|
||||||
|
|
||||||
close-request => $close_request();
|
close-request => $close_request();
|
||||||
|
realize => $realize();
|
||||||
notify::config => $notify_config();
|
notify::config => $notify_config();
|
||||||
notify::fullscreened => $notify_fullscreened();
|
notify::fullscreened => $notify_fullscreened();
|
||||||
notify::maximized => $notify_maximized();
|
notify::maximized => $notify_maximized();
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@ const gdk = @import("gdk");
|
||||||
const Config = @import("../../config.zig").Config;
|
const Config = @import("../../config.zig").Config;
|
||||||
const input = @import("../../input.zig");
|
const input = @import("../../input.zig");
|
||||||
const key = @import("key.zig");
|
const key = @import("key.zig");
|
||||||
|
const ApprtWindow = @import("class/window.zig").Window;
|
||||||
// TODO: As we get to these APIs the compiler should tell us
|
|
||||||
const ApprtWindow = void;
|
|
||||||
|
|
||||||
pub const noop = @import("winproto/noop.zig");
|
pub const noop = @import("winproto/noop.zig");
|
||||||
pub const x11 = @import("winproto/x11.zig");
|
pub const x11 = @import("winproto/x11.zig");
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ const gdk = @import("gdk");
|
||||||
|
|
||||||
const Config = @import("../../../config.zig").Config;
|
const Config = @import("../../../config.zig").Config;
|
||||||
const input = @import("../../../input.zig");
|
const input = @import("../../../input.zig");
|
||||||
const ApprtWindow = void; // TODO: fix
|
const ApprtWindow = @import("../class/window.zig").Window;
|
||||||
|
|
||||||
const log = std.log.scoped(.winproto_noop);
|
const log = std.log.scoped(.winproto_noop);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ const wayland = @import("wayland");
|
||||||
|
|
||||||
const Config = @import("../../../config.zig").Config;
|
const Config = @import("../../../config.zig").Config;
|
||||||
const input = @import("../../../input.zig");
|
const input = @import("../../../input.zig");
|
||||||
const ApprtWindow = void; // TODO: fix
|
const ApprtWindow = @import("../class/window.zig").Window;
|
||||||
|
|
||||||
const wl = wayland.client.wl;
|
const wl = wayland.client.wl;
|
||||||
const org = wayland.client.org;
|
const org = wayland.client.org;
|
||||||
|
|
@ -257,7 +257,7 @@ pub const Window = struct {
|
||||||
) !Window {
|
) !Window {
|
||||||
_ = alloc;
|
_ = alloc;
|
||||||
|
|
||||||
const gtk_native = apprt_window.window.as(gtk.Native);
|
const gtk_native = apprt_window.as(gtk.Native);
|
||||||
const gdk_surface = gtk_native.getSurface() orelse return error.NotWaylandSurface;
|
const gdk_surface = gtk_native.getSurface() orelse return error.NotWaylandSurface;
|
||||||
|
|
||||||
// This should never fail, because if we're being called at this point
|
// This should never fail, because if we're being called at this point
|
||||||
|
|
@ -470,14 +470,14 @@ pub const Window = struct {
|
||||||
monitor: *gdk.Monitor,
|
monitor: *gdk.Monitor,
|
||||||
apprt_window: *ApprtWindow,
|
apprt_window: *ApprtWindow,
|
||||||
) callconv(.c) void {
|
) callconv(.c) void {
|
||||||
const window = apprt_window.window.as(gtk.Window);
|
const window = apprt_window.as(gtk.Window);
|
||||||
const config = &apprt_window.config;
|
const config = if (apprt_window.getConfig()) |v| v.get() else return;
|
||||||
|
|
||||||
var monitor_size: gdk.Rectangle = undefined;
|
var monitor_size: gdk.Rectangle = undefined;
|
||||||
monitor.getGeometry(&monitor_size);
|
monitor.getGeometry(&monitor_size);
|
||||||
|
|
||||||
const dims = config.quick_terminal_size.calculate(
|
const dims = config.@"quick-terminal-size".calculate(
|
||||||
config.quick_terminal_position,
|
config.@"quick-terminal-position",
|
||||||
.{
|
.{
|
||||||
.width = @intCast(monitor_size.f_width),
|
.width = @intCast(monitor_size.f_width),
|
||||||
.height = @intCast(monitor_size.f_height),
|
.height = @intCast(monitor_size.f_height),
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ pub const c = @cImport({
|
||||||
|
|
||||||
const input = @import("../../../input.zig");
|
const input = @import("../../../input.zig");
|
||||||
const Config = @import("../../../config.zig").Config;
|
const Config = @import("../../../config.zig").Config;
|
||||||
const ApprtWindow = void; // TODO: fix
|
const ApprtWindow = @import("../class/window.zig").Window;
|
||||||
|
|
||||||
const log = std.log.scoped(.gtk_x11);
|
const log = std.log.scoped(.gtk_x11);
|
||||||
|
|
||||||
|
|
@ -170,8 +170,7 @@ pub const App = struct {
|
||||||
|
|
||||||
pub const Window = struct {
|
pub const Window = struct {
|
||||||
app: *App,
|
app: *App,
|
||||||
config: *const ApprtWindow.DerivedConfig,
|
apprt_window: *ApprtWindow,
|
||||||
gtk_window: *adw.ApplicationWindow,
|
|
||||||
x11_surface: *gdk_x11.X11Surface,
|
x11_surface: *gdk_x11.X11Surface,
|
||||||
|
|
||||||
blur_region: Region = .{},
|
blur_region: Region = .{},
|
||||||
|
|
@ -183,9 +182,8 @@ pub const Window = struct {
|
||||||
) !Window {
|
) !Window {
|
||||||
_ = alloc;
|
_ = alloc;
|
||||||
|
|
||||||
const surface = apprt_window.window.as(
|
const surface = apprt_window.as(gtk.Native).getSurface() orelse
|
||||||
gtk.Native,
|
return error.NotX11Surface;
|
||||||
).getSurface() orelse return error.NotX11Surface;
|
|
||||||
|
|
||||||
const x11_surface = gobject.ext.cast(
|
const x11_surface = gobject.ext.cast(
|
||||||
gdk_x11.X11Surface,
|
gdk_x11.X11Surface,
|
||||||
|
|
@ -194,8 +192,7 @@ pub const Window = struct {
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.app = app,
|
.app = app,
|
||||||
.config = &apprt_window.config,
|
.apprt_window = apprt_window,
|
||||||
.gtk_window = apprt_window.window,
|
|
||||||
.x11_surface = x11_surface,
|
.x11_surface = x11_surface,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -221,10 +218,10 @@ pub const Window = struct {
|
||||||
var x: f64 = 0;
|
var x: f64 = 0;
|
||||||
var y: f64 = 0;
|
var y: f64 = 0;
|
||||||
|
|
||||||
self.gtk_window.as(gtk.Native).getSurfaceTransform(&x, &y);
|
self.apprt_window.as(gtk.Native).getSurfaceTransform(&x, &y);
|
||||||
|
|
||||||
// Transform surface coordinates to device coordinates.
|
// Transform surface coordinates to device coordinates.
|
||||||
const scale: f64 = @floatFromInt(self.gtk_window.as(gtk.Widget).getScaleFactor());
|
const scale: f64 = @floatFromInt(self.apprt_window.as(gtk.Widget).getScaleFactor());
|
||||||
x *= scale;
|
x *= scale;
|
||||||
y *= scale;
|
y *= scale;
|
||||||
|
|
||||||
|
|
@ -257,10 +254,10 @@ pub const Window = struct {
|
||||||
// and I think it's not really noticeable enough to justify the effort.
|
// and I think it's not really noticeable enough to justify the effort.
|
||||||
// (Wayland also has this visual artifact anyway...)
|
// (Wayland also has this visual artifact anyway...)
|
||||||
|
|
||||||
const gtk_widget = self.gtk_window.as(gtk.Widget);
|
const gtk_widget = self.apprt_window.as(gtk.Widget);
|
||||||
|
|
||||||
// Transform surface coordinates to device coordinates.
|
// Transform surface coordinates to device coordinates.
|
||||||
const scale = self.gtk_window.as(gtk.Widget).getScaleFactor();
|
const scale = self.apprt_window.as(gtk.Widget).getScaleFactor();
|
||||||
self.blur_region.width = gtk_widget.getWidth() * scale;
|
self.blur_region.width = gtk_widget.getWidth() * scale;
|
||||||
self.blur_region.height = gtk_widget.getHeight() * scale;
|
self.blur_region.height = gtk_widget.getHeight() * scale;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue