mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-23 08:47:47 +02:00
macOS: React to changes in effective appearance of the NSApplication not the content view for each window
This is nicer now every OS Windows doesnt cause a notification. Also fixes #9034 which was caused by us setting an explicit appearance on the window when the titlebar is set to a specific color thereby preventing the views in the window from getting appearance change notifications.
This commit is contained in:
@@ -147,6 +147,10 @@ Detailed list of changes
|
|||||||
- macOS: Workaround for bug in macOS Tahoe that caused closed OS Windows to
|
- macOS: Workaround for bug in macOS Tahoe that caused closed OS Windows to
|
||||||
remain as invisible rectangles that intercept mouse events (:iss:`8952`)
|
remain as invisible rectangles that intercept mouse events (:iss:`8952`)
|
||||||
|
|
||||||
|
- macOS: Fix a regression in the previous release that broke automatic
|
||||||
|
switching of dark/light mode when setting :opt:`macos_titlebar_color` to a
|
||||||
|
arbitrary color (:iss:`9034`)
|
||||||
|
|
||||||
- goto_session: Add ``--sort-by=alphabetical`` to have the interactive session
|
- goto_session: Add ``--sort-by=alphabetical`` to have the interactive session
|
||||||
picker list the sessions in a fixed order rather than by most recent
|
picker list the sessions in a fixed order rather than by most recent
|
||||||
(:disc:`9033`)
|
(:disc:`9033`)
|
||||||
|
|||||||
@@ -297,6 +297,7 @@ static NSDictionary<NSString*,NSNumber*> *global_shortcuts = nil;
|
|||||||
// Delegate for application related notifications {{{
|
// Delegate for application related notifications {{{
|
||||||
|
|
||||||
@interface GLFWApplicationDelegate : NSObject <NSApplicationDelegate>
|
@interface GLFWApplicationDelegate : NSObject <NSApplicationDelegate>
|
||||||
|
- (void)handleAppearanceChange;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GLFWApplicationDelegate
|
@implementation GLFWApplicationDelegate
|
||||||
@@ -415,20 +416,73 @@ static GLFWapplicationwillfinishlaunchingfun finish_launching_callback = NULL;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *AppearanceObservationContext = &AppearanceObservationContext;
|
||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
if (finish_launching_callback) finish_launching_callback(true);
|
|
||||||
(void)notification;
|
(void)notification;
|
||||||
|
[[NSApplication sharedApplication] addObserver:self
|
||||||
|
forKeyPath:@"effectiveAppearance" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
|
||||||
|
context:AppearanceObservationContext];
|
||||||
|
|
||||||
|
if (finish_launching_callback) finish_launching_callback(true);
|
||||||
[NSApp stop:nil];
|
[NSApp stop:nil];
|
||||||
|
|
||||||
CGDisplayRegisterReconfigurationCallback(display_reconfigured, NULL);
|
CGDisplayRegisterReconfigurationCallback(display_reconfigured, NULL);
|
||||||
_glfwCocoaPostEmptyEvent();
|
_glfwCocoaPostEmptyEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWColorScheme glfwGetCurrentSystemColorTheme(bool query_if_unintialized) {
|
||||||
|
(void)query_if_unintialized;
|
||||||
|
int theme_type = GLFW_COLOR_SCHEME_NO_PREFERENCE;
|
||||||
|
NSAppearance *changedAppearance = NSApp.effectiveAppearance;
|
||||||
|
NSAppearanceName newAppearance = [changedAppearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
|
||||||
|
if([newAppearance isEqualToString:NSAppearanceNameDarkAqua]){
|
||||||
|
theme_type = GLFW_COLOR_SCHEME_DARK;
|
||||||
|
} else {
|
||||||
|
theme_type = GLFW_COLOR_SCHEME_LIGHT;
|
||||||
|
}
|
||||||
|
return theme_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||||
|
ofObject:(id)object
|
||||||
|
change:(NSDictionary<NSKeyValueChangeKey, id> *)change
|
||||||
|
context:(void *)context {
|
||||||
|
if (context == AppearanceObservationContext) {
|
||||||
|
if ([keyPath isEqualToString:@"effectiveAppearance"]) {
|
||||||
|
// The initial call (from NSKeyValueObservingOptionInitial) might happen on a background thread.
|
||||||
|
// Dispatch to the main thread to be safe, especially if updating UI.
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[self handleAppearanceChange];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If the context doesn't match, pass the notification to the superclass.
|
||||||
|
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleAppearanceChange {
|
||||||
|
static GLFWColorScheme previously_reported_appearance = GLFW_COLOR_SCHEME_NO_PREFERENCE;
|
||||||
|
GLFWColorScheme new_appearance = glfwGetCurrentSystemColorTheme(true);
|
||||||
|
if (new_appearance != previously_reported_appearance) {
|
||||||
|
previously_reported_appearance = new_appearance;
|
||||||
|
_glfwInputColorScheme(new_appearance, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
(void)aNotification;
|
(void)aNotification;
|
||||||
CGDisplayRemoveReconfigurationCallback(display_reconfigured, NULL);
|
CGDisplayRemoveReconfigurationCallback(display_reconfigured, NULL);
|
||||||
|
@try {
|
||||||
|
[[NSApplication sharedApplication] removeObserver:self
|
||||||
|
forKeyPath:@"effectiveAppearance"
|
||||||
|
context:AppearanceObservationContext];
|
||||||
|
} @catch (NSException * __unused exception) {
|
||||||
|
// Ignore exceptions, which can happen if the observer was never added.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidHide:(NSNotification *)notification
|
- (void)applicationDidHide:(NSNotification *)notification
|
||||||
|
|||||||
@@ -981,16 +981,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
updateCursorImage(window);
|
updateCursorImage(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidChangeEffectiveAppearance
|
|
||||||
{
|
|
||||||
static GLFWColorScheme appearance = GLFW_COLOR_SCHEME_NO_PREFERENCE;
|
|
||||||
GLFWColorScheme new_appearance = glfwGetCurrentSystemColorTheme(true);
|
|
||||||
if (new_appearance != appearance) {
|
|
||||||
appearance = new_appearance;
|
|
||||||
_glfwInputColorScheme(appearance, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewDidChangeBackingProperties
|
- (void)viewDidChangeBackingProperties
|
||||||
{
|
{
|
||||||
if (!window) return;
|
if (!window) return;
|
||||||
@@ -3434,20 +3424,6 @@ GLFWAPI void glfwCocoaSetWindowChrome(GLFWwindow *w, unsigned int color, bool us
|
|||||||
[window->ns.object makeFirstResponder:window->ns.view];
|
[window->ns.object makeFirstResponder:window->ns.view];
|
||||||
}}
|
}}
|
||||||
|
|
||||||
GLFWAPI GLFWColorScheme glfwGetCurrentSystemColorTheme(bool query_if_unintialized) {
|
|
||||||
(void)query_if_unintialized;
|
|
||||||
int theme_type = 0;
|
|
||||||
NSAppearance *changedAppearance = NSApp.effectiveAppearance;
|
|
||||||
NSAppearanceName newAppearance = [changedAppearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
|
|
||||||
if([newAppearance isEqualToString:NSAppearanceNameDarkAqua]){
|
|
||||||
theme_type = 1;
|
|
||||||
} else {
|
|
||||||
theme_type = 2;
|
|
||||||
}
|
|
||||||
return theme_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLFWAPI uint32_t
|
GLFWAPI uint32_t
|
||||||
glfwGetCocoaKeyEquivalent(uint32_t glfw_key, int glfw_mods, int *cocoa_mods) {
|
glfwGetCocoaKeyEquivalent(uint32_t glfw_key, int glfw_mods, int *cocoa_mods) {
|
||||||
*cocoa_mods = 0;
|
*cocoa_mods = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user