summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-08-20 10:06:20 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-08-20 10:06:20 +0300
commit61893d79662bfd5e8aa12d48ebc632d560955af5 (patch)
tree9aaeca4160a696550ed95d58f2851485d9f8d5bf /src
parent36f6b98f6835ed2a93d29f4937ac4d9cfd87a485 (diff)
Added system theme setting
Diffstat (limited to 'src')
-rw-r--r--src/app.c37
-rw-r--r--src/ui/macos.m42
-rw-r--r--src/ui/util.c8
3 files changed, 81 insertions, 6 deletions
diff --git a/src/app.c b/src/app.c
index 670adee2..3eb090a6 100644
--- a/src/app.c
+++ b/src/app.c
@@ -70,6 +70,7 @@ struct Impl_App {
70 float uiScale; 70 float uiScale;
71 int zoomPercent; 71 int zoomPercent;
72 enum iColorTheme theme; 72 enum iColorTheme theme;
73 iBool useSystemTheme;
73}; 74};
74 75
75static iApp app_; 76static iApp app_;
@@ -113,7 +114,8 @@ static iString *serializePrefs_App_(const iApp *d) {
113 appendFormat_String(str, "sidebar.mode arg:%d\n", mode_SidebarWidget(sidebar)); 114 appendFormat_String(str, "sidebar.mode arg:%d\n", mode_SidebarWidget(sidebar));
114 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window)); 115 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window));
115 appendFormat_String(str, "zoom.set arg:%d\n", d->zoomPercent); 116 appendFormat_String(str, "zoom.set arg:%d\n", d->zoomPercent);
116 appendFormat_String(str, "theme.set arg:%d\n", d->theme); 117 appendFormat_String(str, "theme.set arg:%d auto:1\n", d->theme);
118 appendFormat_String(str, "ostheme arg:%d\n", d->useSystemTheme);
117 return str; 119 return str;
118} 120}
119 121
@@ -234,6 +236,7 @@ static void init_App_(iApp *d, int argc, char **argv) {
234 d->commandEcho = checkArgument_CommandLine(&d->args, "echo") != NULL; 236 d->commandEcho = checkArgument_CommandLine(&d->args, "echo") != NULL;
235 d->initialWindowRect = init_Rect(-1, -1, 800, 500); 237 d->initialWindowRect = init_Rect(-1, -1, 800, 500);
236 d->theme = dark_ColorTheme; 238 d->theme = dark_ColorTheme;
239 d->useSystemTheme = iTrue;
237 d->running = iFalse; 240 d->running = iFalse;
238 d->window = NULL; 241 d->window = NULL;
239 d->retainWindowSize = iTrue; 242 d->retainWindowSize = iTrue;
@@ -452,11 +455,20 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) {
452 toFloat_String(text_InputWidget(findChild_Widget(d, "prefs.uiscale")))); 455 toFloat_String(text_InputWidget(findChild_Widget(d, "prefs.uiscale"))));
453 postCommandf_App("retainwindow arg:%d", 456 postCommandf_App("retainwindow arg:%d",
454 isSelected_Widget(findChild_Widget(d, "prefs.retainwindow"))); 457 isSelected_Widget(findChild_Widget(d, "prefs.retainwindow")));
458 postCommandf_App("ostheme arg:%d",
459 isSelected_Widget(findChild_Widget(d, "prefs.ostheme")));
455 destroy_Widget(d); 460 destroy_Widget(d);
456 return iTrue; 461 return iTrue;
457 } 462 }
458 else if (equal_Command(cmd, "theme.changed")) { 463 else if (equal_Command(cmd, "prefs.ostheme.changed")) {
464 //setToggle_Widget(findChild_Widget(d, "prefs.ostheme"), arg_Command(cmd));
465 postCommandf_App("ostheme arg:%d", arg_Command(cmd));
466 }
467 else if (equal_Command(cmd, "theme.changed")) {
459 updatePrefsThemeButtons_(d); 468 updatePrefsThemeButtons_(d);
469 if (!argLabel_Command(cmd, "auto")) {
470 setToggle_Widget(findChild_Widget(d, "prefs.ostheme"), iFalse);
471 }
460 } 472 }
461 return iFalse; 473 return iFalse;
462} 474}
@@ -601,6 +613,7 @@ iBool handleCommand_App(const char *cmd) {
601 else if (equal_Command(cmd, "preferences")) { 613 else if (equal_Command(cmd, "preferences")) {
602 iWidget *dlg = makePreferences_Widget(); 614 iWidget *dlg = makePreferences_Widget();
603 updatePrefsThemeButtons_(dlg); 615 updatePrefsThemeButtons_(dlg);
616 setToggle_Widget(findChild_Widget(dlg, "prefs.ostheme"), d->useSystemTheme);
604 setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->retainWindowSize); 617 setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->retainWindowSize);
605 setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"), 618 setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"),
606 collectNewFormat_String("%g", uiScale_Window(d->window))); 619 collectNewFormat_String("%g", uiScale_Window(d->window)));
@@ -641,11 +654,29 @@ iBool handleCommand_App(const char *cmd) {
641 return iTrue; 654 return iTrue;
642 } 655 }
643 else if (equal_Command(cmd, "theme.set")) { 656 else if (equal_Command(cmd, "theme.set")) {
657 const int isAuto = argLabel_Command(cmd, "auto");
644 d->theme = arg_Command(cmd); 658 d->theme = arg_Command(cmd);
659 if (!isAuto) {
660 postCommand_App("ostheme arg:0");
661 }
645 setThemePalette_Color(d->theme); 662 setThemePalette_Color(d->theme);
646 postCommand_App("theme.changed"); 663 postCommandf_App("theme.changed auto:%d", isAuto);
664 return iTrue;
665 }
666 else if (equal_Command(cmd, "ostheme")) {
667 d->useSystemTheme = arg_Command(cmd);
647 return iTrue; 668 return iTrue;
648 } 669 }
670 else if (equal_Command(cmd, "os.theme.changed")) {
671 if (d->useSystemTheme) {
672 const int dark = argLabel_Command(cmd, "dark");
673 const int contrast = argLabel_Command(cmd, "contrast");
674 postCommandf_App("theme.set arg:%d auto:1",
675 dark ? (contrast ? pureBlack_ColorTheme : dark_ColorTheme)
676 : (contrast ? pureWhite_ColorTheme : light_ColorTheme));
677 }
678 return iFalse;
679 }
649 else { 680 else {
650 return iFalse; 681 return iFalse;
651 } 682 }
diff --git a/src/ui/macos.m b/src/ui/macos.m
index 9ff2f96e..75a3ffe4 100644
--- a/src/ui/macos.m
+++ b/src/ui/macos.m
@@ -91,6 +91,7 @@ enum iTouchBarVariant {
91 91
92@interface MyDelegate : NSResponder<NSApplicationDelegate, NSTouchBarDelegate> { 92@interface MyDelegate : NSResponder<NSApplicationDelegate, NSTouchBarDelegate> {
93 enum iTouchBarVariant touchBarVariant; 93 enum iTouchBarVariant touchBarVariant;
94 NSString *currentAppearanceName;
94 NSObject<NSApplicationDelegate> *sdlDelegate; 95 NSObject<NSApplicationDelegate> *sdlDelegate;
95 NSMutableDictionary<NSString *, NSString*> *menuCommands; 96 NSMutableDictionary<NSString *, NSString*> *menuCommands;
96} 97}
@@ -105,6 +106,7 @@ enum iTouchBarVariant {
105 106
106- (id)initWithSDLDelegate:(NSObject<NSApplicationDelegate> *)sdl { 107- (id)initWithSDLDelegate:(NSObject<NSApplicationDelegate> *)sdl {
107 [super init]; 108 [super init];
109 currentAppearanceName = nil;
108 menuCommands = [[NSMutableDictionary<NSString *, NSString *> alloc] init]; 110 menuCommands = [[NSMutableDictionary<NSString *, NSString *> alloc] init];
109 touchBarVariant = default_TouchBarVariant; 111 touchBarVariant = default_TouchBarVariant;
110 sdlDelegate = sdl; 112 sdlDelegate = sdl;
@@ -113,6 +115,7 @@ enum iTouchBarVariant {
113 115
114- (void)dealloc { 116- (void)dealloc {
115 [menuCommands release]; 117 [menuCommands release];
118 [currentAppearanceName release];
116 [super dealloc]; 119 [super dealloc];
117} 120}
118 121
@@ -121,6 +124,24 @@ enum iTouchBarVariant {
121 self.touchBar = nil; 124 self.touchBar = nil;
122} 125}
123 126
127static void appearanceChanged_MacOS_(NSString *name) {
128 const iBool isDark = [name containsString:@"Dark"];
129 const iBool isHighContrast = [name containsString:@"HighContrast"];
130 postCommandf_App("os.theme.changed dark:%d contrast:%d", isDark ? 1 : 0, isHighContrast ? 1 : 0);
131 printf("Effective appearance changed: %s\n", [name cStringUsingEncoding:NSUTF8StringEncoding]);
132 fflush(stdout);
133}
134
135- (void)setAppearance:(NSString *)name {
136 if (!currentAppearanceName || ![name isEqualToString:currentAppearanceName]) {
137 if (currentAppearanceName) {
138 [currentAppearanceName release];
139 }
140 currentAppearanceName = [name retain];
141 appearanceChanged_MacOS_(currentAppearanceName);
142 }
143}
144
124- (void)setCommand:(NSString *)command forMenuItem:(NSMenuItem *)menuItem { 145- (void)setCommand:(NSString *)command forMenuItem:(NSMenuItem *)menuItem {
125 [menuCommands setObject:command forKey:[menuItem title]]; 146 [menuCommands setObject:command forKey:[menuItem title]];
126} 147}
@@ -133,6 +154,16 @@ enum iTouchBarVariant {
133 [sdlDelegate applicationDidFinishLaunching:notification]; 154 [sdlDelegate applicationDidFinishLaunching:notification];
134} 155}
135 156
157- (void)observeValueForKeyPath:(NSString *)keyPath
158 ofObject:(id)object
159 change:(NSDictionary *)change
160 context:(void *)context {
161 iUnused(object, change);
162 if ([keyPath isEqualToString:@"effectiveAppearance"] && context == self) {
163 [self setAppearance:[[NSApp effectiveAppearance] name]];
164 }
165}
166
136#if 0 167#if 0
137- (NSTouchBar *)makeTouchBar { 168- (NSTouchBar *)makeTouchBar {
138 NSTouchBar *bar = [[NSTouchBar alloc] init]; 169 NSTouchBar *bar = [[NSTouchBar alloc] init];
@@ -344,8 +375,10 @@ void enableMomentumScroll_MacOS(void) {
344 375
345void setupApplication_MacOS(void) { 376void setupApplication_MacOS(void) {
346 NSApplication *app = [NSApplication sharedApplication]; 377 NSApplication *app = [NSApplication sharedApplication];
378 //appearanceChanged_MacOS_([[app effectiveAppearance] name]);
347 /* Our delegate will override SDL's delegate. */ 379 /* Our delegate will override SDL's delegate. */
348 MyDelegate *myDel = [[MyDelegate alloc] initWithSDLDelegate:app.delegate]; 380 MyDelegate *myDel = [[MyDelegate alloc] initWithSDLDelegate:app.delegate];
381 [myDel setAppearance:[[app effectiveAppearance] name]];
349 app.delegate = myDel; 382 app.delegate = myDel;
350 NSMenu *appMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu]; 383 NSMenu *appMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu];
351 NSMenuItem *prefsItem = [appMenu itemWithTitle:@"Preferences…"]; 384 NSMenuItem *prefsItem = [appMenu itemWithTitle:@"Preferences…"];
@@ -361,6 +394,10 @@ void setupApplication_MacOS(void) {
361void insertMenuItems_MacOS(const char *menuLabel, int atIndex, const iMenuItem *items, size_t count) { 394void insertMenuItems_MacOS(const char *menuLabel, int atIndex, const iMenuItem *items, size_t count) {
362 NSApplication *app = [NSApplication sharedApplication]; 395 NSApplication *app = [NSApplication sharedApplication];
363 MyDelegate *myDel = (MyDelegate *) app.delegate; 396 MyDelegate *myDel = (MyDelegate *) app.delegate;
397 [app addObserver:myDel
398 forKeyPath:@"effectiveAppearance"
399 options:0
400 context:myDel];
364 NSMenu *appMenu = [app mainMenu]; 401 NSMenu *appMenu = [app mainMenu];
365 NSMenuItem *mainItem = [appMenu insertItemWithTitle:[NSString stringWithUTF8String:menuLabel] 402 NSMenuItem *mainItem = [appMenu insertItemWithTitle:[NSString stringWithUTF8String:menuLabel]
366 action:nil 403 action:nil
@@ -417,6 +454,11 @@ void insertMenuItems_MacOS(const char *menuLabel, int atIndex, const iMenuItem *
417} 454}
418 455
419void handleCommand_MacOS(const char *cmd) { 456void handleCommand_MacOS(const char *cmd) {
457 if (equal_Command(cmd, "prefs.ostheme.changed")) {
458 if (arg_Command(cmd)) {
459 appearanceChanged_MacOS_([[NSApp effectiveAppearance] name]);
460 }
461 }
420#if 0 462#if 0
421 if (equal_Command(cmd, "tabs.changed")) { 463 if (equal_Command(cmd, "tabs.changed")) {
422 MyDelegate *myDel = (MyDelegate *) [[NSApplication sharedApplication] delegate]; 464 MyDelegate *myDel = (MyDelegate *) [[NSApplication sharedApplication] delegate];
diff --git a/src/ui/util.c b/src/ui/util.c
index 9f4768d9..918a0671 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -702,9 +702,11 @@ iWidget *makePreferences_Widget(void) {
702 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); 702 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);
703 iWidget *values = addChildFlags_Widget( 703 iWidget *values = addChildFlags_Widget(
704 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); 704 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);
705// setBackgroundColor_Widget(headings, none_ColorId); 705#if defined (iPlatformApple) || defined (iPlatformMSys)
706// setBackgroundColor_Widget(values, none_ColorId); 706 addChild_Widget(headings, iClob(makeHeading_Widget("Use system theme:")));
707 addChild_Widget(headings, iClob(makeHeading_Widget("Theme:"))); 707 addChild_Widget(values, iClob(makeToggle_Widget("prefs.ostheme")));
708#endif
709 addChild_Widget(headings, iClob(makeHeading_Widget("Theme:")));
708 iWidget *themes = new_Widget(); 710 iWidget *themes = new_Widget();
709 /* Themes. */ { 711 /* Themes. */ {
710 setId_Widget(addChild_Widget(themes, iClob(new_LabelWidget("Pure Black", 0, 0, "theme.set arg:0"))), "prefs.theme.0"); 712 setId_Widget(addChild_Widget(themes, iClob(new_LabelWidget("Pure Black", 0, 0, "theme.set arg:0"))), "prefs.theme.0");