From 5730262e0d6760c32f51df0e1bcac96fe2944c37 Mon Sep 17 00:00:00 2001 From: Liang-Ting Chen Date: Sun, 6 Oct 2019 17:12:47 +0100 Subject: [PATCH] [fix #766] Add a variable (and an event) for OS appearance (change) --- runtime/doc/autocmd.txt | 7 +++++++ runtime/doc/eval.txt | 12 ++++++++++++ runtime/doc/gui_mac.txt | 4 ++++ runtime/doc/tags | 3 +++ src/MacVim/MMBackend.m | 14 ++++++++++++++ src/MacVim/MMVimController.h | 2 ++ src/MacVim/MMVimController.m | 11 +++++++++++ src/MacVim/MMVimView.m | 4 ++++ src/MacVim/MacVim.h | 1 + src/MacVim/Miscellaneous.h | 2 ++ src/MacVim/Miscellaneous.m | 23 +++++++++++++++++++++++ src/autocmd.c | 1 + src/evalvars.c | 1 + src/vim.h | 4 +++- 14 files changed, 88 insertions(+), 1 deletion(-) diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 95618e659f..587b3d0a6f 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -290,6 +290,8 @@ Name triggered by ~ |EncodingChanged| after the 'encoding' option has been changed |TermChanged| after the value of 'term' has changed |OptionSet| after setting any option +|OSAppearanceChanged| after the variable |v:os_appearance| has changed + {only in MacVim GUI} Startup and exit |VimEnter| after doing all the startup stuff @@ -918,6 +920,11 @@ OptionSet After setting an option. The pattern is When using |:set| in the autocommand the event is not triggered again. + *OSAppearanceChanged* +OSAppearanceChanged After changing the variable |v:os_appearance|. + This change happens only if the OS changes + its appearance and Vim is running with a GUI. + *QuickFixCmdPre* QuickFixCmdPre Before a quickfix command is run (|:make|, |:lmake|, |:grep|, |:lgrep|, |:grepadd|, diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 387b96f0c6..3d9563c7e0 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2033,6 +2033,18 @@ v:operator The last operator given in Normal mode. This is a single commands. Read-only. + *v:os_appearance* *os-appearance-variable* +v:os_appearance The current OS appearance mode. Useful if you want to change + options |background| or |colorscheme| according to the + appearance of the GUI frontend. See also |OSAppearanceChanged|. + value description ~ + 0 Light Mode (always 0 on unsupported platforms) + 1 Dark Mode + 2 High-Contrast Light Mode + 3 High-Contrast Dark Mode + + {only in MacVim GUI} + *v:prevcount* *prevcount-variable* v:prevcount The count given for the last but one Normal mode command. This is the v:count value of the previous command. Useful if diff --git a/runtime/doc/gui_mac.txt b/runtime/doc/gui_mac.txt index be52c435a9..0fc7a509d6 100644 --- a/runtime/doc/gui_mac.txt +++ b/runtime/doc/gui_mac.txt @@ -121,6 +121,10 @@ These are the non-standard options that MacVim supports: These are the non-standard commands that MacVim supports: |:macaction| |:macmenu| + *macvim-autocommands* +These are the non-standard events that MacVim supports: + |OSAppearanceChanged| + *macvim-find* Whenever you search for something in Vim (e.g. using "/"), or hit when you have text selected, the search query is copied to the macOS "Find diff --git a/runtime/doc/tags b/runtime/doc/tags index 4e4ba93eb8..9a59e8e1ca 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -4996,6 +4996,7 @@ OS390-bugs os_390.txt /*OS390-bugs* OS390-has-ebcdic os_390.txt /*OS390-has-ebcdic* OS390-limitations os_390.txt /*OS390-limitations* OS390-open-source os_390.txt /*OS390-open-source* +OSAppearanceChanged autocmd.txt /*OSAppearanceChanged* OffTheSpot mbyte.txt /*OffTheSpot* OnTheSpot mbyte.txt /*OnTheSpot* Operator-pending intro.txt /*Operator-pending* @@ -8274,6 +8275,7 @@ options.txt options.txt /*options.txt* optwin options.txt /*optwin* or() eval.txt /*or()* oracle ft_sql.txt /*oracle* +os-appearance-variable eval.txt /*os-appearance-variable* os2 os_os2.txt /*os2* os390 os_390.txt /*os390* os_390.txt os_390.txt /*os_390.txt* @@ -9753,6 +9755,7 @@ v:option_old eval.txt /*v:option_old* v:option_oldglobal eval.txt /*v:option_oldglobal* v:option_oldlocal eval.txt /*v:option_oldlocal* v:option_type eval.txt /*v:option_type* +v:os_appearance eval.txt /*v:os_appearance* v:prevcount eval.txt /*v:prevcount* v:profiling eval.txt /*v:profiling* v:progname eval.txt /*v:progname* diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index 7ea6bd0a8c..61eaa59680 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -198,6 +198,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); - (void)useSelectionForFind; - (void)handleMarkedText:(NSData *)data; - (void)handleGesture:(NSData *)data; +- (void)handleOSAppearanceChange:(NSData *)data; #ifdef FEAT_BEVAL - (void)bevalCallback:(id)sender; #endif @@ -2110,6 +2111,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font); ASLogDebug(@"SetWindowPositionMsgID: x=%d y=%d", winposX, winposY); } else if (GestureMsgID == msgid) { [self handleGesture:data]; + } else if (NotifyAppearanceChangeMsgID == msgid) { + [self handleOSAppearanceChange:data]; } else if (ActivatedImMsgID == msgid) { [self setImState:YES]; } else if (DeactivatedImMsgID == msgid) { @@ -3326,6 +3329,17 @@ extern GuiFont gui_mch_retain_font(GuiFont font); } } +- (void)handleOSAppearanceChange:(NSData *)data { + const void *bytes = [data bytes]; + int flag = *((int*)bytes); bytes += sizeof(int); + // 0 : (default) The standard (light) system appearance. + // 1 : The standard dark system appearance. + // 2 : The high-contrast version of the standard light system appearance. + // 3 : The high-contrast version of the standard dark system appearance. + set_vim_var_nr(VV_OS_APPEARANCE, flag); + apply_autocmds(EVENT_OSAPPCHANGED, NULL, NULL, FALSE, curbuf); +} + #ifdef FEAT_BEVAL - (void)bevalCallback:(id)sender { diff --git a/src/MacVim/MMVimController.h b/src/MacVim/MMVimController.h index 892a4f4149..b93295ae44 100644 --- a/src/MacVim/MMVimController.h +++ b/src/MacVim/MMVimController.h @@ -67,6 +67,8 @@ - (void)file:(NSString *)filename draggedToTabAtIndex:(NSUInteger)tabIndex; - (void)filesDraggedToTabBar:(NSArray *)filenames; - (void)dropString:(NSString *)string; +- (void)appearanceChanged:(int)flag; + - (void)passArguments:(NSDictionary *)args; - (void)sendMessage:(int)msgid data:(NSData *)data; - (BOOL)sendMessageNow:(int)msgid data:(NSData *)data diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index 811ecbaa61..b42551092c 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -176,6 +176,10 @@ static BOOL isUnsafeMessage(int msgid); isInitialized = YES; + // After MMVimController's initialization is completed, + // set up the variable `v:os_appearance`. + [self appearanceChanged:getCurrentAppearance([windowController vimView].effectiveAppearance)]; + return self; } @@ -358,6 +362,13 @@ static BOOL isUnsafeMessage(int msgid); } } +- (void)appearanceChanged:(int)flag +{ + [self sendMessage:NotifyAppearanceChangeMsgID + data:[NSData dataWithBytes: &flag + length:sizeof(flag)]]; +} + - (void)passArguments:(NSDictionary *)args { if (!args) return; diff --git a/src/MacVim/MMVimView.m b/src/MacVim/MMVimView.m index 7b1738fc79..6624c5c6db 100644 --- a/src/MacVim/MMVimView.m +++ b/src/MacVim/MMVimView.m @@ -664,6 +664,10 @@ enum { [self frameSizeMayHaveChanged:NO]; } +- (void)viewDidChangeEffectiveAppearance +{ + [vimController appearanceChanged:getCurrentAppearance(self.effectiveAppearance)]; +} @end // MMVimView diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index a6ca42e78b..080f3031b0 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -261,6 +261,7 @@ extern const char * const MMVimMsgIDStrings[]; MSG(AddToMRUMsgID) \ MSG(BackingPropertiesChangedMsgID) \ MSG(SetBlurRadiusMsgID) \ + MSG(NotifyAppearanceChangeMsgID) \ MSG(EnableLigaturesMsgID) \ MSG(DisableLigaturesMsgID) \ MSG(EnableThinStrokesMsgID) \ diff --git a/src/MacVim/Miscellaneous.h b/src/MacVim/Miscellaneous.h index 75dfd269ed..5d8c24ace1 100644 --- a/src/MacVim/Miscellaneous.h +++ b/src/MacVim/Miscellaneous.h @@ -160,3 +160,5 @@ NSArray *normalizeFilenames(NSArray *filenames); BOOL shouldUseYosemiteTabBarStyle(); BOOL shouldUseMojaveTabBarStyle(); BOOL shouldUseBufferedDrawing(); + +int getCurrentAppearance(NSAppearance *appearance); diff --git a/src/MacVim/Miscellaneous.m b/src/MacVim/Miscellaneous.m index c76830850a..74fd8dabc4 100644 --- a/src/MacVim/Miscellaneous.m +++ b/src/MacVim/Miscellaneous.m @@ -330,3 +330,26 @@ shouldUseBufferedDrawing() #endif return NO; } + + +int +getCurrentAppearance(NSAppearance *appearance){ + int flag = 0; // for macOS 10.13 or eariler always return 0; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_14 + if (@available(macOS 10.14, *)) { + NSAppearanceName appearanceName = [appearance bestMatchFromAppearancesWithNames: + @[NSAppearanceNameAqua + , NSAppearanceNameDarkAqua + , NSAppearanceNameAccessibilityHighContrastAqua + , NSAppearanceNameAccessibilityHighContrastDarkAqua]]; + if ([appearanceName isEqualToString:NSAppearanceNameDarkAqua]) { + flag = 1; + } else if ([appearanceName isEqualToString:NSAppearanceNameAccessibilityHighContrastAqua]) { + flag = 2; + } else if ([appearanceName isEqualToString:NSAppearanceNameAccessibilityHighContrastDarkAqua]) { + flag = 3; + } + } +#endif + return flag; +} diff --git a/src/autocmd.c b/src/autocmd.c index 3f87e931cd..4bdcedf939 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -151,6 +151,7 @@ static struct event_name {"InsertCharPre", EVENT_INSERTCHARPRE}, {"MenuPopup", EVENT_MENUPOPUP}, {"OptionSet", EVENT_OPTIONSET}, + {"OSAppearanceChanged", EVENT_OSAPPCHANGED}, {"QuickFixCmdPost", EVENT_QUICKFIXCMDPOST}, {"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE}, {"QuitPre", EVENT_QUITPRE}, diff --git a/src/evalvars.c b/src/evalvars.c index 08a9cc2e14..9ac9626206 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -143,6 +143,7 @@ static struct vimvar {VV_NAME("event", VAR_DICT), VV_RO}, {VV_NAME("versionlong", VAR_NUMBER), VV_RO}, {VV_NAME("echospace", VAR_NUMBER), VV_RO}, + {VV_NAME("os_appearance", VAR_NUMBER), VV_RO}, }; // shorthand diff --git a/src/vim.h b/src/vim.h index 038493b13f..73534e17e8 100644 --- a/src/vim.h +++ b/src/vim.h @@ -1322,6 +1322,7 @@ enum auto_event EVENT_INSERTLEAVE, // when leaving Insert mode EVENT_MENUPOPUP, // just before popup menu is displayed EVENT_OPTIONSET, // option was set + EVENT_OSAPPCHANGED, // after changing the OS appearance EVENT_QUICKFIXCMDPOST, // after :make, :grep etc. EVENT_QUICKFIXCMDPRE, // before :make, :grep etc. EVENT_QUITPRE, // before :quit @@ -1992,7 +1993,8 @@ typedef int sock_T; #define VV_EVENT 90 #define VV_VERSIONLONG 91 #define VV_ECHOSPACE 92 -#define VV_LEN 93 // number of v: vars +#define VV_OS_APPEARANCE 93 +#define VV_LEN 94 // number of v: vars // used for v_number in VAR_SPECIAL #define VVAL_FALSE 0L