diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 37 | ||||
-rw-r--r-- | src/ui/macos.m | 42 | ||||
-rw-r--r-- | src/ui/util.c | 8 |
3 files changed, 81 insertions, 6 deletions
@@ -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 | ||
75 | static iApp app_; | 76 | static 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 | ||
127 | static 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 | ||
345 | void setupApplication_MacOS(void) { | 376 | void 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) { | |||
361 | void insertMenuItems_MacOS(const char *menuLabel, int atIndex, const iMenuItem *items, size_t count) { | 394 | void 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 | ||
419 | void handleCommand_MacOS(const char *cmd) { | 456 | void 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"); |