Skip to content

Commit 43fd164

Browse files
committed
feat: dark mode support toggle
1 parent ae27bd3 commit 43fd164

File tree

6 files changed

+94
-24
lines changed

6 files changed

+94
-24
lines changed

.github/workflows/binary.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
strategy:
2121
fail-fast: false
2222
matrix:
23-
zig-version: [master]
23+
zig-version: ["0.11.0"]
2424
targets:
2525
- "x86-windows"
2626
- "x86_64-windows"
@@ -58,7 +58,7 @@ jobs:
5858
strategy:
5959
fail-fast: false
6060
matrix:
61-
zig-version: [master]
61+
zig-version: ["0.11.0"]
6262
targets:
6363
- "x86_64-macos"
6464
- "aarch64-macos"

.tool-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
zig 0.11.0

README.org

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#+DATE: 2023-10-21T12:09:48+0800
2-
#+LASTMOD: 2023-11-09T22:26:31+0800
2+
#+LASTMOD: 2023-11-10T21:49:29+0800
33
#+TYPE: docs
44

55
* Zigcli
@@ -24,7 +24,7 @@ This package provides:
2424
- =repeat=, repeat a command until it succeeds.
2525
- =pidof=, like [[https://man7.org/linux/man-pages/man1/pidof.1.html][pidof]], but for macOS.
2626
- =night-shift=, control [[https://support.apple.com/guide/mac-help/use-night-shift-mchl97bc676d/mac][Night Shift]] in macOS.
27-
- =dark-mode=, Get dark mode status in macOS.
27+
- =dark-mode=, control dark mode in macOS.
2828

2929
* Install
3030
** Programs

build.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ fn makeCompileStep(
199199
exe.linkFramework("CoreBrightness");
200200
} else if (std.mem.eql(u8, name, "dark-mode")) {
201201
exe.linkSystemLibrary("objc");
202-
exe.linkFramework("AppKit");
202+
exe.addFrameworkPath(.{ .path = "/System/Library/PrivateFrameworks" });
203+
exe.linkFramework("SkyLight");
203204
}
204205
return exe;
205206
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,17 @@
11
* Dark mode
22
Get dark mode status for macOS.
3+
#+begin_src bash
4+
$ dark-mode -h
5+
USAGE:
6+
dark-mode [OPTIONS] [--] <command>
7+
8+
Available commands:
9+
status View dark mode status
10+
on Turn dark mode on
11+
off Turn dark mode off
12+
toggle Toggle dark mode
13+
14+
OPTIONS:
15+
-v, --version Print version
16+
-h, --help Print help information
17+
#+end_src

src/bin/dark-mode.zig

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,84 @@
11
//! Dark mode status, built for macOS.
22
//!
33
const std = @import("std");
4+
const simargs = @import("simargs");
5+
const util = @import("util.zig");
46
const c = @cImport({
57
@cInclude("objc/objc.h");
68
@cInclude("objc/message.h");
79
});
810

9-
// https://developer.apple.com/documentation/appkit/nsappearancenamedarkaqua
10-
const darkValue = "NSAppearanceNameDarkAqua";
11+
// https://saagarjha.com/blog/2018/12/01/scheduling-dark-mode/
12+
extern "c" fn SLSSetAppearanceThemeLegacy(bool) void;
13+
extern "c" fn SLSGetAppearanceThemeLegacy() bool;
14+
15+
const Command = enum {
16+
Status,
17+
On,
18+
Off,
19+
Toggle,
20+
21+
const FromString = std.ComptimeStringMap(@This(), .{
22+
.{ "status", .Status },
23+
.{ "on", .On },
24+
.{ "off", .Off },
25+
.{ "toggle", .Toggle },
26+
});
27+
};
1128

1229
pub fn main() !void {
13-
const clazz = c.objc_getClass("NSAppearance");
14-
15-
const appearanceName = blk: {
16-
const call: *fn (c.id, c.SEL) callconv(.C) c.id = @constCast(@ptrCast(&c.objc_msgSend));
17-
const appearance = call(@alignCast(@ptrCast(clazz.?)), c.sel_registerName("currentDrawingAppearance"));
18-
break :blk call(appearance, c.sel_registerName("name"));
19-
};
20-
21-
const appearanceValue = blk: {
22-
const call: *fn (c.id, c.SEL) callconv(.C) [*c]const u8 = @constCast(@ptrCast(&c.objc_msgSend));
23-
break :blk call(appearanceName, c.sel_registerName("UTF8String"));
24-
};
25-
26-
if (std.mem.eql(u8, darkValue, std.mem.span(appearanceValue.?))) {
27-
std.debug.print("on", .{});
28-
} else {
29-
std.debug.print("off", .{});
30+
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
31+
defer arena.deinit();
32+
const allocator = arena.allocator();
33+
34+
const opt = try simargs.parse(allocator, struct {
35+
version: bool = false,
36+
help: bool = false,
37+
38+
pub const __shorts__ = .{
39+
.version = .v,
40+
.help = .h,
41+
};
42+
43+
pub const __messages__ = .{
44+
.help = "Print help information",
45+
.version = "Print version",
46+
};
47+
},
48+
\\<command>
49+
\\
50+
\\ Available commands:
51+
\\ status View dark mode status
52+
\\ on Turn dark mode on
53+
\\ off Turn dark mode off
54+
\\ toggle Toggle dark mode
55+
, util.get_build_info());
56+
defer opt.deinit();
57+
58+
var args_iter = util.SliceIter([]const u8).init(opt.positional_args.items);
59+
const cmd: Command = if (args_iter.next()) |v|
60+
Command.FromString.get(v) orelse return error.UnknownCommand
61+
else
62+
.Status;
63+
64+
switch (cmd) {
65+
.Status => {
66+
const is_dark = SLSGetAppearanceThemeLegacy();
67+
if (is_dark) {
68+
std.debug.print("on", .{});
69+
} else {
70+
std.debug.print("off", .{});
71+
}
72+
},
73+
.On => {
74+
SLSSetAppearanceThemeLegacy(true);
75+
},
76+
.Off => {
77+
SLSSetAppearanceThemeLegacy(false);
78+
},
79+
.Toggle => {
80+
const is_dark = SLSGetAppearanceThemeLegacy();
81+
SLSSetAppearanceThemeLegacy(!is_dark);
82+
},
3083
}
3184
}

0 commit comments

Comments
 (0)