Skip to content

Commit

Permalink
feat: dark mode support toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
jiacai2050 committed Nov 10, 2023
1 parent ae27bd3 commit 9a11f56
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 22 deletions.
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
zig 0.11.0
4 changes: 2 additions & 2 deletions README.org
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#+DATE: 2023-10-21T12:09:48+0800
#+LASTMOD: 2023-11-09T22:26:31+0800
#+LASTMOD: 2023-11-10T21:49:29+0800
#+TYPE: docs

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

* Install
** Programs
Expand Down
3 changes: 2 additions & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ fn makeCompileStep(
exe.linkFramework("CoreBrightness");
} else if (std.mem.eql(u8, name, "dark-mode")) {
exe.linkSystemLibrary("objc");
exe.linkFramework("AppKit");
exe.addFrameworkPath(.{ .path = "/System/Library/PrivateFrameworks" });
exe.linkFramework("SkyLight");
}
return exe;
}
15 changes: 15 additions & 0 deletions docs/content/docs/programs/dark-mode.org
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
* Dark mode
Get dark mode status for macOS.
#+begin_src bash
$ dark-mode -h
USAGE:
dark-mode [OPTIONS] [--] <command>

Available commands:
status View dark mode status
on Turn dark mode on
off Turn dark mode off
toggle Toggle dark mode

OPTIONS:
-v, --version Print version
-h, --help Print help information
#+end_src
91 changes: 72 additions & 19 deletions src/bin/dark-mode.zig
Original file line number Diff line number Diff line change
@@ -1,31 +1,84 @@
//! Dark mode status, built for macOS.
//!
const std = @import("std");
const simargs = @import("simargs");
const util = @import("util.zig");
const c = @cImport({
@cInclude("objc/objc.h");
@cInclude("objc/message.h");
});

// https://developer.apple.com/documentation/appkit/nsappearancenamedarkaqua
const darkValue = "NSAppearanceNameDarkAqua";
// https://saagarjha.com/blog/2018/12/01/scheduling-dark-mode/
extern "c" fn SLSSetAppearanceThemeLegacy(bool) void;
extern "c" fn SLSGetAppearanceThemeLegacy() bool;

const Command = enum {
Status,
On,
Off,
Toggle,

const FromString = std.ComptimeStringMap(@This(), .{
.{ "status", .Status },
.{ "on", .On },
.{ "off", .Off },
.{ "toggle", .Toggle },
});
};

pub fn main() !void {
const clazz = c.objc_getClass("NSAppearance");

const appearanceName = blk: {
const call: *fn (c.id, c.SEL) callconv(.C) c.id = @constCast(@ptrCast(&c.objc_msgSend));
const appearance = call(@alignCast(@ptrCast(clazz.?)), c.sel_registerName("currentDrawingAppearance"));
break :blk call(appearance, c.sel_registerName("name"));
};

const appearanceValue = blk: {
const call: *fn (c.id, c.SEL) callconv(.C) [*c]const u8 = @constCast(@ptrCast(&c.objc_msgSend));
break :blk call(appearanceName, c.sel_registerName("UTF8String"));
};

if (std.mem.eql(u8, darkValue, std.mem.span(appearanceValue.?))) {
std.debug.print("on", .{});
} else {
std.debug.print("off", .{});
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();

const opt = try simargs.parse(allocator, struct {
version: bool = false,
help: bool = false,

pub const __shorts__ = .{
.version = .v,
.help = .h,
};

pub const __messages__ = .{
.help = "Print help information",
.version = "Print version",
};
},
\\<command>
\\
\\ Available commands:
\\ status View dark mode status
\\ on Turn dark mode on
\\ off Turn dark mode off
\\ toggle Toggle dark mode
, util.get_build_info());
defer opt.deinit();

var args_iter = util.SliceIter([]const u8).init(opt.positional_args.items);
const cmd: Command = if (args_iter.next()) |v|
Command.FromString.get(v) orelse return error.UnknownCommand
else
.Status;

switch (cmd) {
.Status => {
const is_dark = SLSGetAppearanceThemeLegacy();
if (is_dark) {
std.debug.print("on", .{});
} else {
std.debug.print("off", .{});
}
},
.On => {
SLSSetAppearanceThemeLegacy(true);
},
.Off => {
SLSSetAppearanceThemeLegacy(false);
},
.Toggle => {
const is_dark = SLSGetAppearanceThemeLegacy();
SLSSetAppearanceThemeLegacy(!is_dark);
},
}
}

0 comments on commit 9a11f56

Please sign in to comment.