Merge pull request #1446 from jcollie/gtk-mode-2031

Implement mode 2031 and DSR 996 for GTK
This commit is contained in:
Mitchell Hashimoto
2024-02-02 20:02:47 -08:00
committed by GitHub
2 changed files with 108 additions and 0 deletions

View File

@ -13,12 +13,14 @@ const App = @This();
const std = @import("std");
const assert = std.debug.assert;
const builtin = @import("builtin");
const apprt = @import("../../apprt.zig");
const configpkg = @import("../../config.zig");
const input = @import("../../input.zig");
const internal_os = @import("../../os/main.zig");
const Config = configpkg.Config;
const CoreApp = @import("../../App.zig");
const CoreSurface = @import("../../Surface.zig");
const build_options = @import("build_options");
const Surface = @import("Surface.zig");
@ -223,6 +225,22 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
// https://gitlab.gnome.org/GNOME/glib/-/blob/bd2ccc2f69ecfd78ca3f34ab59e42e2b462bad65/gio/gapplication.c#L2302
c.g_application_activate(gapp);
// Register for dbus events
if (c.g_application_get_dbus_connection(gapp)) |dbus_connection| {
_ = c.g_dbus_connection_signal_subscribe(
dbus_connection,
null,
"org.freedesktop.portal.Settings",
"SettingChanged",
"/org/freedesktop/portal/desktop",
"org.freedesktop.appearance",
c.G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE,
&gtkNotifyColorScheme,
core_app,
null,
);
}
return .{
.core_app = core_app,
.app = app,
@ -488,6 +506,93 @@ fn gtkActivate(app: *c.GtkApplication, ud: ?*anyopaque) callconv(.C) void {
}, .{ .forever = {} });
}
/// Call a D-Bus method to determine the current color scheme. If there
/// is any error at any point we'll log the error and return "light"
pub fn getColorScheme(self: *App) apprt.ColorScheme {
const dbus_connection = c.g_application_get_dbus_connection(@ptrCast(self.app));
var err: ?*c.GError = null;
defer if (err) |e| c.g_error_free(e);
const value = c.g_dbus_connection_call_sync(
dbus_connection,
"org.freedesktop.portal.Desktop",
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.Settings",
"ReadOne",
c.g_variant_new("(ss)", "org.freedesktop.appearance", "color-scheme"),
c.G_VARIANT_TYPE("(v)"),
c.G_DBUS_CALL_FLAGS_NONE,
-1,
null,
&err,
) orelse {
if (err) |e| log.err("unable to get current color scheme: {s}", .{e.message});
return .light;
};
defer c.g_variant_unref(value);
if (c.g_variant_is_of_type(value, c.G_VARIANT_TYPE("(v)")) == 1) {
var inner: ?*c.GVariant = null;
c.g_variant_get(value, "(v)", &inner);
defer c.g_variant_unref(inner);
if (c.g_variant_is_of_type(inner, c.G_VARIANT_TYPE("u")) == 1) {
return if (c.g_variant_get_uint32(inner) == 1) .dark else .light;
}
}
return .light;
}
/// This will be called by D-Bus when the style changes between light & dark.
fn gtkNotifyColorScheme(
_: ?*c.GDBusConnection,
_: [*c]const u8,
_: [*c]const u8,
_: [*c]const u8,
_: [*c]const u8,
parameters: ?*c.GVariant,
user_data: ?*anyopaque,
) callconv(.C) void {
const core_app: *CoreApp = @ptrCast(@alignCast(user_data orelse {
log.err("style change notification: userdata is null", .{});
return;
}));
if (c.g_variant_is_of_type(parameters, c.G_VARIANT_TYPE("(ssv)")) != 1) {
log.err("unexpected parameter type: {s}", .{c.g_variant_get_type_string(parameters)});
return;
}
var namespace: [*c]u8 = undefined;
var setting: [*c]u8 = undefined;
var value: *c.GVariant = undefined;
c.g_variant_get(parameters, "(ssv)", &namespace, &setting, &value);
defer c.g_free(namespace);
defer c.g_free(setting);
defer c.g_variant_unref(value);
// ignore any setting changes that we aren't interested in
if (!std.mem.eql(u8, "org.freedesktop.appearance", std.mem.span(namespace))) return;
if (!std.mem.eql(u8, "color-scheme", std.mem.span(setting))) return;
if (c.g_variant_is_of_type(value, c.G_VARIANT_TYPE("u")) != 1) {
log.err("unexpected value type: {s}", .{c.g_variant_get_type_string(value)});
return;
}
const color_scheme: apprt.ColorScheme = if (c.g_variant_get_uint32(value) == 1)
.dark
else
.light;
for (core_app.surfaces.items) |surface| {
surface.core_surface.colorSchemeCallback(color_scheme) catch |err| {
log.err("unable to tell surface about color scheme change: {}", .{err});
};
}
}
fn gtkActionOpenConfig(
_: *c.GSimpleAction,
_: *c.GVariant,

View File

@ -418,6 +418,9 @@ fn realize(self: *Surface) !void {
self.core_surface.setFontSize(size);
}
// Set the intial color scheme
try self.core_surface.colorSchemeCallback(self.app.getColorScheme());
// Note we're realized
self.realized = true;
}