diff options
| author | Alan Third | 2017-08-20 21:14:47 +0100 |
|---|---|---|
| committer | Alan Third | 2017-08-23 19:57:00 +0100 |
| commit | 7baa50eca28ff21497b058fa22656bbb4a447d87 (patch) | |
| tree | 248e7eae805b65b76f368f70928cdcfb1a54cb84 /src | |
| parent | 4309d1574ae86244751600171b605b2b2eca4697 (diff) | |
| download | emacs-7baa50eca28ff21497b058fa22656bbb4a447d87.tar.gz emacs-7baa50eca28ff21497b058fa22656bbb4a447d87.zip | |
Add ability to change macOS WM theme (bug#27973)
* src/frame.c (make_frame, frame_parms, syms_of_frame)
[NS_IMPL_COCOA]: Add ns-appearance and ns-transparent-titlebar
options.
* src/frame.h (ns_appearance_type) [NS_IMPL_COCOA]: Add enum to
represent NSAppearance options.
(struct frame) [NS_IMPL_COCOA]: Add ns_appearance and
ns_transparent_titlebar frame parameters.
* src/nsfns.m (ns_frame_parm_handlers) [NS_IMPL_COCOA]: Add
ns_set_appearance and ns_set_transparent_titlebar handlers.
(Sx_create_frame): Handle ns-appearance and ns-transparent-titlebar
frame parameters.
(Qdark): Add new symbol for use with ns-appearance.
* src/nsterm.h (ns_set_appearance, ns_set_transparent_titlebar)
[NS_IMPL_COCOA]: Add prototypes.
* src/nsterm.m (ns_set_appearance, ns_set_transparent_titlebar)
[NS_IMPL_COCOA]: New functions.
(initFrameFromEmacs) [NS_IMPL_COCOA]: Handle ns-appearance and
ns-transparent-titlebar frame parameters.
* doc/lispref/frames.texi (Window Management Parameters): Document
ns-apperance and ns-transparent-titlebar.
Diffstat (limited to 'src')
| -rw-r--r-- | src/frame.c | 12 | ||||
| -rw-r--r-- | src/frame.h | 18 | ||||
| -rw-r--r-- | src/nsfns.m | 17 | ||||
| -rw-r--r-- | src/nsterm.h | 7 | ||||
| -rw-r--r-- | src/nsterm.m | 68 |
5 files changed, 122 insertions, 0 deletions
diff --git a/src/frame.c b/src/frame.c index 1e5e4bbdb48..5099f75be4d 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -834,6 +834,10 @@ make_frame (bool mini_p) | |||
| 834 | #if ! defined (USE_GTK) && ! defined (HAVE_NS) | 834 | #if ! defined (USE_GTK) && ! defined (HAVE_NS) |
| 835 | f->last_tool_bar_item = -1; | 835 | f->last_tool_bar_item = -1; |
| 836 | #endif | 836 | #endif |
| 837 | #ifdef NS_IMPL_COCOA | ||
| 838 | f->ns_appearance = ns_appearance_aqua; | ||
| 839 | f->ns_transparent_titlebar = false; | ||
| 840 | #endif | ||
| 837 | #endif | 841 | #endif |
| 838 | 842 | ||
| 839 | root_window = make_window (); | 843 | root_window = make_window (); |
| @@ -3520,6 +3524,10 @@ static const struct frame_parm_table frame_parms[] = | |||
| 3520 | {"z-group", SYMBOL_INDEX (Qz_group)}, | 3524 | {"z-group", SYMBOL_INDEX (Qz_group)}, |
| 3521 | {"override-redirect", SYMBOL_INDEX (Qoverride_redirect)}, | 3525 | {"override-redirect", SYMBOL_INDEX (Qoverride_redirect)}, |
| 3522 | {"no-special-glyphs", SYMBOL_INDEX (Qno_special_glyphs)}, | 3526 | {"no-special-glyphs", SYMBOL_INDEX (Qno_special_glyphs)}, |
| 3527 | #ifdef NS_IMPL_COCOA | ||
| 3528 | {"ns-appearance", SYMBOL_INDEX (Qns_appearance)}, | ||
| 3529 | {"ns-transparent-titlebar", SYMBOL_INDEX (Qns_transparent_titlebar)}, | ||
| 3530 | #endif | ||
| 3523 | }; | 3531 | }; |
| 3524 | 3532 | ||
| 3525 | #ifdef HAVE_WINDOW_SYSTEM | 3533 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -5646,6 +5654,10 @@ syms_of_frame (void) | |||
| 5646 | #ifdef HAVE_NS | 5654 | #ifdef HAVE_NS |
| 5647 | DEFSYM (Qns_parse_geometry, "ns-parse-geometry"); | 5655 | DEFSYM (Qns_parse_geometry, "ns-parse-geometry"); |
| 5648 | #endif | 5656 | #endif |
| 5657 | #ifdef NS_IMPL_COCOA | ||
| 5658 | DEFSYM (Qns_appearance, "ns-appearance"); | ||
| 5659 | DEFSYM (Qns_transparent_titlebar, "ns-transparent-titlebar"); | ||
| 5660 | #endif | ||
| 5649 | 5661 | ||
| 5650 | DEFSYM (Qalpha, "alpha"); | 5662 | DEFSYM (Qalpha, "alpha"); |
| 5651 | DEFSYM (Qauto_lower, "auto-lower"); | 5663 | DEFSYM (Qauto_lower, "auto-lower"); |
diff --git a/src/frame.h b/src/frame.h index 154dc9a3bb4..4b7e448b543 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -65,6 +65,14 @@ enum internal_border_part | |||
| 65 | INTERNAL_BORDER_BOTTOM_EDGE, | 65 | INTERNAL_BORDER_BOTTOM_EDGE, |
| 66 | INTERNAL_BORDER_BOTTOM_LEFT_CORNER, | 66 | INTERNAL_BORDER_BOTTOM_LEFT_CORNER, |
| 67 | }; | 67 | }; |
| 68 | |||
| 69 | #ifdef NS_IMPL_COCOA | ||
| 70 | enum ns_appearance_type | ||
| 71 | { | ||
| 72 | ns_appearance_aqua, | ||
| 73 | ns_appearance_vibrant_dark | ||
| 74 | }; | ||
| 75 | #endif | ||
| 68 | #endif /* HAVE_WINDOW_SYSTEM */ | 76 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 69 | 77 | ||
| 70 | /* The structure representing a frame. */ | 78 | /* The structure representing a frame. */ |
| @@ -563,6 +571,12 @@ struct frame | |||
| 563 | /* All display backends seem to need these two pixel values. */ | 571 | /* All display backends seem to need these two pixel values. */ |
| 564 | unsigned long background_pixel; | 572 | unsigned long background_pixel; |
| 565 | unsigned long foreground_pixel; | 573 | unsigned long foreground_pixel; |
| 574 | |||
| 575 | #ifdef NS_IMPL_COCOA | ||
| 576 | /* NSAppearance theme used on this frame. */ | ||
| 577 | enum ns_appearance_type ns_appearance; | ||
| 578 | bool_bf ns_transparent_titlebar; | ||
| 579 | #endif | ||
| 566 | }; | 580 | }; |
| 567 | 581 | ||
| 568 | /* Most code should use these functions to set Lisp fields in struct frame. */ | 582 | /* Most code should use these functions to set Lisp fields in struct frame. */ |
| @@ -953,6 +967,10 @@ default_pixels_per_inch_y (void) | |||
| 953 | #define FRAME_Z_GROUP_ABOVE_SUSPENDED(f) \ | 967 | #define FRAME_Z_GROUP_ABOVE_SUSPENDED(f) \ |
| 954 | ((f)->z_group == z_group_above_suspended) | 968 | ((f)->z_group == z_group_above_suspended) |
| 955 | #define FRAME_Z_GROUP_BELOW(f) ((f)->z_group == z_group_below) | 969 | #define FRAME_Z_GROUP_BELOW(f) ((f)->z_group == z_group_below) |
| 970 | #ifdef NS_IMPL_COCOA | ||
| 971 | #define FRAME_NS_APPEARANCE(f) ((f)->ns_appearance) | ||
| 972 | #define FRAME_NS_TRANSPARENT_TITLEBAR(f) ((f)->ns_transparent_titlebar) | ||
| 973 | #endif | ||
| 956 | #else /* not HAVE_WINDOW_SYSTEM */ | 974 | #else /* not HAVE_WINDOW_SYSTEM */ |
| 957 | #define FRAME_UNDECORATED(f) ((void) (f), 0) | 975 | #define FRAME_UNDECORATED(f) ((void) (f), 0) |
| 958 | #define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0) | 976 | #define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0) |
diff --git a/src/nsfns.m b/src/nsfns.m index e19e4e2641a..b00441eb79f 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -985,6 +985,10 @@ frame_parm_handler ns_frame_parm_handlers[] = | |||
| 985 | x_set_z_group, /* x_set_z_group */ | 985 | x_set_z_group, /* x_set_z_group */ |
| 986 | 0, /* x_set_override_redirect */ | 986 | 0, /* x_set_override_redirect */ |
| 987 | x_set_no_special_glyphs, | 987 | x_set_no_special_glyphs, |
| 988 | #ifdef NS_IMPL_COCOA | ||
| 989 | ns_set_appearance, | ||
| 990 | ns_set_transparent_titlebar, | ||
| 991 | #endif | ||
| 988 | }; | 992 | }; |
| 989 | 993 | ||
| 990 | 994 | ||
| @@ -1277,6 +1281,18 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 1277 | FRAME_UNDECORATED (f) = !NILP (tem) && !EQ (tem, Qunbound); | 1281 | FRAME_UNDECORATED (f) = !NILP (tem) && !EQ (tem, Qunbound); |
| 1278 | store_frame_param (f, Qundecorated, FRAME_UNDECORATED (f) ? Qt : Qnil); | 1282 | store_frame_param (f, Qundecorated, FRAME_UNDECORATED (f) ? Qt : Qnil); |
| 1279 | 1283 | ||
| 1284 | #ifdef NS_IMPL_COCOA | ||
| 1285 | tem = x_get_arg (dpyinfo, parms, Qns_appearance, NULL, NULL, RES_TYPE_SYMBOL); | ||
| 1286 | FRAME_NS_APPEARANCE (f) = EQ (tem, Qdark) | ||
| 1287 | ? ns_appearance_vibrant_dark : ns_appearance_aqua; | ||
| 1288 | store_frame_param (f, Qns_appearance, tem); | ||
| 1289 | |||
| 1290 | tem = x_get_arg (dpyinfo, parms, Qns_transparent_titlebar, | ||
| 1291 | NULL, NULL, RES_TYPE_BOOLEAN); | ||
| 1292 | FRAME_NS_TRANSPARENT_TITLEBAR (f) = !NILP (tem) && !EQ (tem, Qunbound); | ||
| 1293 | store_frame_param (f, Qns_transparent_titlebar, tem); | ||
| 1294 | #endif | ||
| 1295 | |||
| 1280 | parent_frame = x_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL, | 1296 | parent_frame = x_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL, |
| 1281 | RES_TYPE_SYMBOL); | 1297 | RES_TYPE_SYMBOL); |
| 1282 | /* Accept parent-frame iff parent-id was not specified. */ | 1298 | /* Accept parent-frame iff parent-id was not specified. */ |
| @@ -3248,6 +3264,7 @@ syms_of_nsfns (void) | |||
| 3248 | DEFSYM (Qfontsize, "fontsize"); | 3264 | DEFSYM (Qfontsize, "fontsize"); |
| 3249 | DEFSYM (Qframe_title_format, "frame-title-format"); | 3265 | DEFSYM (Qframe_title_format, "frame-title-format"); |
| 3250 | DEFSYM (Qicon_title_format, "icon-title-format"); | 3266 | DEFSYM (Qicon_title_format, "icon-title-format"); |
| 3267 | DEFSYM (Qdark, "dark"); | ||
| 3251 | 3268 | ||
| 3252 | DEFVAR_LISP ("ns-icon-type-alist", Vns_icon_type_alist, | 3269 | DEFVAR_LISP ("ns-icon-type-alist", Vns_icon_type_alist, |
| 3253 | doc: /* Alist of elements (REGEXP . IMAGE) for images of icons associated to frames. | 3270 | doc: /* Alist of elements (REGEXP . IMAGE) for images of icons associated to frames. |
diff --git a/src/nsterm.h b/src/nsterm.h index 0ac8043e264..65b7a0347ac 100644 --- a/src/nsterm.h +++ b/src/nsterm.h | |||
| @@ -1210,6 +1210,13 @@ extern void x_set_no_accept_focus (struct frame *f, Lisp_Object new_value, | |||
| 1210 | Lisp_Object old_value); | 1210 | Lisp_Object old_value); |
| 1211 | extern void x_set_z_group (struct frame *f, Lisp_Object new_value, | 1211 | extern void x_set_z_group (struct frame *f, Lisp_Object new_value, |
| 1212 | Lisp_Object old_value); | 1212 | Lisp_Object old_value); |
| 1213 | #ifdef NS_IMPL_COCOA | ||
| 1214 | extern void ns_set_appearance (struct frame *f, Lisp_Object new_value, | ||
| 1215 | Lisp_Object old_value); | ||
| 1216 | extern void ns_set_transparent_titlebar (struct frame *f, | ||
| 1217 | Lisp_Object new_value, | ||
| 1218 | Lisp_Object old_value); | ||
| 1219 | #endif | ||
| 1213 | extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds, | 1220 | extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds, |
| 1214 | fd_set *exceptfds, struct timespec *timeout, | 1221 | fd_set *exceptfds, struct timespec *timeout, |
| 1215 | sigset_t *sigmask); | 1222 | sigset_t *sigmask); |
diff --git a/src/nsterm.m b/src/nsterm.m index 95092b29c89..22f8efd6b96 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -2036,6 +2036,58 @@ x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | |||
| 2036 | error ("Invalid z-group specification"); | 2036 | error ("Invalid z-group specification"); |
| 2037 | } | 2037 | } |
| 2038 | 2038 | ||
| 2039 | #ifdef NS_IMPL_COCOA | ||
| 2040 | void | ||
| 2041 | ns_set_appearance (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 2042 | { | ||
| 2043 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 | ||
| 2044 | EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); | ||
| 2045 | NSWindow *window = [view window]; | ||
| 2046 | |||
| 2047 | NSTRACE ("ns_set_appearance"); | ||
| 2048 | |||
| 2049 | #ifndef NSAppKitVersionNumber10_9 | ||
| 2050 | #define NSAppKitVersionNumber10_9 1265 | ||
| 2051 | #endif | ||
| 2052 | |||
| 2053 | if (NSAppKitVersionNumber < NSAppKitVersionNumber10_9) | ||
| 2054 | return; | ||
| 2055 | |||
| 2056 | if (EQ (new_value, Qdark)) | ||
| 2057 | { | ||
| 2058 | window.appearance = [NSAppearance | ||
| 2059 | appearanceNamed: NSAppearanceNameVibrantDark]; | ||
| 2060 | FRAME_NS_APPEARANCE (f) = ns_appearance_vibrant_dark; | ||
| 2061 | } | ||
| 2062 | else | ||
| 2063 | { | ||
| 2064 | window.appearance = [NSAppearance | ||
| 2065 | appearanceNamed: NSAppearanceNameAqua]; | ||
| 2066 | FRAME_NS_APPEARANCE (f) = ns_appearance_aqua; | ||
| 2067 | } | ||
| 2068 | #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 */ | ||
| 2069 | } | ||
| 2070 | |||
| 2071 | void | ||
| 2072 | ns_set_transparent_titlebar (struct frame *f, Lisp_Object new_value, | ||
| 2073 | Lisp_Object old_value) | ||
| 2074 | { | ||
| 2075 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 | ||
| 2076 | EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); | ||
| 2077 | NSWindow *window = [view window]; | ||
| 2078 | |||
| 2079 | NSTRACE ("ns_set_transparent_titlebar"); | ||
| 2080 | |||
| 2081 | if ([window respondsToSelector: @selector(titlebarAppearsTransparent)] | ||
| 2082 | && !EQ (new_value, old_value)) | ||
| 2083 | { | ||
| 2084 | window.titlebarAppearsTransparent = !NILP (new_value); | ||
| 2085 | FRAME_NS_TRANSPARENT_TITLEBAR (f) = !NILP (new_value); | ||
| 2086 | } | ||
| 2087 | #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 */ | ||
| 2088 | } | ||
| 2089 | #endif /* NS_IMPL_COCOA */ | ||
| 2090 | |||
| 2039 | static void | 2091 | static void |
| 2040 | ns_fullscreen_hook (struct frame *f) | 2092 | ns_fullscreen_hook (struct frame *f) |
| 2041 | { | 2093 | { |
| @@ -7083,6 +7135,22 @@ not_in_argv (NSString *arg) | |||
| 7083 | if (! FRAME_UNDECORATED (f)) | 7135 | if (! FRAME_UNDECORATED (f)) |
| 7084 | [self createToolbar: f]; | 7136 | [self createToolbar: f]; |
| 7085 | 7137 | ||
| 7138 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 | ||
| 7139 | #ifndef NSAppKitVersionNumber10_9 | ||
| 7140 | #define NSAppKitVersionNumber10_9 1265 | ||
| 7141 | #endif | ||
| 7142 | |||
| 7143 | if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_9 | ||
| 7144 | && FRAME_NS_APPEARANCE (f) != ns_appearance_aqua) | ||
| 7145 | win.appearance = [NSAppearance | ||
| 7146 | appearanceNamed: NSAppearanceNameVibrantDark]; | ||
| 7147 | #endif | ||
| 7148 | |||
| 7149 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 | ||
| 7150 | if ([win respondsToSelector: @selector(titlebarAppearsTransparent)]) | ||
| 7151 | win.titlebarAppearsTransparent = FRAME_NS_TRANSPARENT_TITLEBAR (f); | ||
| 7152 | #endif | ||
| 7153 | |||
| 7086 | tem = f->icon_name; | 7154 | tem = f->icon_name; |
| 7087 | if (!NILP (tem)) | 7155 | if (!NILP (tem)) |
| 7088 | [win setMiniwindowTitle: | 7156 | [win setMiniwindowTitle: |