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.
This commit is contained in:
parent
4309d1574a
commit
7baa50eca2
6 changed files with 136 additions and 0 deletions
|
@ -2125,6 +2125,20 @@ Specifying this lets you create an Emacs window inside some other
|
|||
application's window. (It is not certain this will be implemented; try
|
||||
it and see if it works.)
|
||||
@end ignore
|
||||
|
||||
@vindex ns-appearance, a frame parameter
|
||||
@item ns-appearance
|
||||
Only available on macOS, if set to @code{dark} draw this frame's
|
||||
window-system window using the ``vibrant dark'' theme, otherwise use
|
||||
the system default. The ``vibrant dark'' theme can be used to set the
|
||||
toolbar and scrollbars to a dark appearance when using an Emacs theme
|
||||
with a dark background.
|
||||
|
||||
@vindex ns-transparent-titlebar, a frame parameter
|
||||
@item ns-transparent-titlebar
|
||||
Only available on macOS, if non-@code{nil}, set the titlebar and
|
||||
toolbar to be transparent. This effectively sets the background color
|
||||
of both to match the Emacs background color.
|
||||
@end table
|
||||
|
||||
|
||||
|
|
12
src/frame.c
12
src/frame.c
|
@ -834,6 +834,10 @@ make_frame (bool mini_p)
|
|||
#if ! defined (USE_GTK) && ! defined (HAVE_NS)
|
||||
f->last_tool_bar_item = -1;
|
||||
#endif
|
||||
#ifdef NS_IMPL_COCOA
|
||||
f->ns_appearance = ns_appearance_aqua;
|
||||
f->ns_transparent_titlebar = false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
root_window = make_window ();
|
||||
|
@ -3520,6 +3524,10 @@ static const struct frame_parm_table frame_parms[] =
|
|||
{"z-group", SYMBOL_INDEX (Qz_group)},
|
||||
{"override-redirect", SYMBOL_INDEX (Qoverride_redirect)},
|
||||
{"no-special-glyphs", SYMBOL_INDEX (Qno_special_glyphs)},
|
||||
#ifdef NS_IMPL_COCOA
|
||||
{"ns-appearance", SYMBOL_INDEX (Qns_appearance)},
|
||||
{"ns-transparent-titlebar", SYMBOL_INDEX (Qns_transparent_titlebar)},
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
|
@ -5646,6 +5654,10 @@ syms_of_frame (void)
|
|||
#ifdef HAVE_NS
|
||||
DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
|
||||
#endif
|
||||
#ifdef NS_IMPL_COCOA
|
||||
DEFSYM (Qns_appearance, "ns-appearance");
|
||||
DEFSYM (Qns_transparent_titlebar, "ns-transparent-titlebar");
|
||||
#endif
|
||||
|
||||
DEFSYM (Qalpha, "alpha");
|
||||
DEFSYM (Qauto_lower, "auto-lower");
|
||||
|
|
18
src/frame.h
18
src/frame.h
|
@ -65,6 +65,14 @@ enum internal_border_part
|
|||
INTERNAL_BORDER_BOTTOM_EDGE,
|
||||
INTERNAL_BORDER_BOTTOM_LEFT_CORNER,
|
||||
};
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
enum ns_appearance_type
|
||||
{
|
||||
ns_appearance_aqua,
|
||||
ns_appearance_vibrant_dark
|
||||
};
|
||||
#endif
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
/* The structure representing a frame. */
|
||||
|
@ -563,6 +571,12 @@ struct frame
|
|||
/* All display backends seem to need these two pixel values. */
|
||||
unsigned long background_pixel;
|
||||
unsigned long foreground_pixel;
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
/* NSAppearance theme used on this frame. */
|
||||
enum ns_appearance_type ns_appearance;
|
||||
bool_bf ns_transparent_titlebar;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Most code should use these functions to set Lisp fields in struct frame. */
|
||||
|
@ -953,6 +967,10 @@ default_pixels_per_inch_y (void)
|
|||
#define FRAME_Z_GROUP_ABOVE_SUSPENDED(f) \
|
||||
((f)->z_group == z_group_above_suspended)
|
||||
#define FRAME_Z_GROUP_BELOW(f) ((f)->z_group == z_group_below)
|
||||
#ifdef NS_IMPL_COCOA
|
||||
#define FRAME_NS_APPEARANCE(f) ((f)->ns_appearance)
|
||||
#define FRAME_NS_TRANSPARENT_TITLEBAR(f) ((f)->ns_transparent_titlebar)
|
||||
#endif
|
||||
#else /* not HAVE_WINDOW_SYSTEM */
|
||||
#define FRAME_UNDECORATED(f) ((void) (f), 0)
|
||||
#define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0)
|
||||
|
|
17
src/nsfns.m
17
src/nsfns.m
|
@ -985,6 +985,10 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
|
|||
x_set_z_group, /* x_set_z_group */
|
||||
0, /* x_set_override_redirect */
|
||||
x_set_no_special_glyphs,
|
||||
#ifdef NS_IMPL_COCOA
|
||||
ns_set_appearance,
|
||||
ns_set_transparent_titlebar,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -1277,6 +1281,18 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
|
|||
FRAME_UNDECORATED (f) = !NILP (tem) && !EQ (tem, Qunbound);
|
||||
store_frame_param (f, Qundecorated, FRAME_UNDECORATED (f) ? Qt : Qnil);
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
tem = x_get_arg (dpyinfo, parms, Qns_appearance, NULL, NULL, RES_TYPE_SYMBOL);
|
||||
FRAME_NS_APPEARANCE (f) = EQ (tem, Qdark)
|
||||
? ns_appearance_vibrant_dark : ns_appearance_aqua;
|
||||
store_frame_param (f, Qns_appearance, tem);
|
||||
|
||||
tem = x_get_arg (dpyinfo, parms, Qns_transparent_titlebar,
|
||||
NULL, NULL, RES_TYPE_BOOLEAN);
|
||||
FRAME_NS_TRANSPARENT_TITLEBAR (f) = !NILP (tem) && !EQ (tem, Qunbound);
|
||||
store_frame_param (f, Qns_transparent_titlebar, tem);
|
||||
#endif
|
||||
|
||||
parent_frame = x_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL,
|
||||
RES_TYPE_SYMBOL);
|
||||
/* Accept parent-frame iff parent-id was not specified. */
|
||||
|
@ -3248,6 +3264,7 @@ - (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
|
|||
DEFSYM (Qfontsize, "fontsize");
|
||||
DEFSYM (Qframe_title_format, "frame-title-format");
|
||||
DEFSYM (Qicon_title_format, "icon-title-format");
|
||||
DEFSYM (Qdark, "dark");
|
||||
|
||||
DEFVAR_LISP ("ns-icon-type-alist", Vns_icon_type_alist,
|
||||
doc: /* Alist of elements (REGEXP . IMAGE) for images of icons associated to frames.
|
||||
|
|
|
@ -1210,6 +1210,13 @@ extern void x_set_no_accept_focus (struct frame *f, Lisp_Object new_value,
|
|||
Lisp_Object old_value);
|
||||
extern void x_set_z_group (struct frame *f, Lisp_Object new_value,
|
||||
Lisp_Object old_value);
|
||||
#ifdef NS_IMPL_COCOA
|
||||
extern void ns_set_appearance (struct frame *f, Lisp_Object new_value,
|
||||
Lisp_Object old_value);
|
||||
extern void ns_set_transparent_titlebar (struct frame *f,
|
||||
Lisp_Object new_value,
|
||||
Lisp_Object old_value);
|
||||
#endif
|
||||
extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds, struct timespec *timeout,
|
||||
sigset_t *sigmask);
|
||||
|
|
68
src/nsterm.m
68
src/nsterm.m
|
@ -2036,6 +2036,58 @@ so some key presses (TAB) are swallowed by the system. */
|
|||
error ("Invalid z-group specification");
|
||||
}
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
void
|
||||
ns_set_appearance (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
|
||||
EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f);
|
||||
NSWindow *window = [view window];
|
||||
|
||||
NSTRACE ("ns_set_appearance");
|
||||
|
||||
#ifndef NSAppKitVersionNumber10_9
|
||||
#define NSAppKitVersionNumber10_9 1265
|
||||
#endif
|
||||
|
||||
if (NSAppKitVersionNumber < NSAppKitVersionNumber10_9)
|
||||
return;
|
||||
|
||||
if (EQ (new_value, Qdark))
|
||||
{
|
||||
window.appearance = [NSAppearance
|
||||
appearanceNamed: NSAppearanceNameVibrantDark];
|
||||
FRAME_NS_APPEARANCE (f) = ns_appearance_vibrant_dark;
|
||||
}
|
||||
else
|
||||
{
|
||||
window.appearance = [NSAppearance
|
||||
appearanceNamed: NSAppearanceNameAqua];
|
||||
FRAME_NS_APPEARANCE (f) = ns_appearance_aqua;
|
||||
}
|
||||
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 */
|
||||
}
|
||||
|
||||
void
|
||||
ns_set_transparent_titlebar (struct frame *f, Lisp_Object new_value,
|
||||
Lisp_Object old_value)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
||||
EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f);
|
||||
NSWindow *window = [view window];
|
||||
|
||||
NSTRACE ("ns_set_transparent_titlebar");
|
||||
|
||||
if ([window respondsToSelector: @selector(titlebarAppearsTransparent)]
|
||||
&& !EQ (new_value, old_value))
|
||||
{
|
||||
window.titlebarAppearsTransparent = !NILP (new_value);
|
||||
FRAME_NS_TRANSPARENT_TITLEBAR (f) = !NILP (new_value);
|
||||
}
|
||||
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 */
|
||||
}
|
||||
#endif /* NS_IMPL_COCOA */
|
||||
|
||||
static void
|
||||
ns_fullscreen_hook (struct frame *f)
|
||||
{
|
||||
|
@ -7083,6 +7135,22 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
|
|||
if (! FRAME_UNDECORATED (f))
|
||||
[self createToolbar: f];
|
||||
|
||||
#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
|
||||
#ifndef NSAppKitVersionNumber10_9
|
||||
#define NSAppKitVersionNumber10_9 1265
|
||||
#endif
|
||||
|
||||
if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_9
|
||||
&& FRAME_NS_APPEARANCE (f) != ns_appearance_aqua)
|
||||
win.appearance = [NSAppearance
|
||||
appearanceNamed: NSAppearanceNameVibrantDark];
|
||||
#endif
|
||||
|
||||
#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
||||
if ([win respondsToSelector: @selector(titlebarAppearsTransparent)])
|
||||
win.titlebarAppearsTransparent = FRAME_NS_TRANSPARENT_TITLEBAR (f);
|
||||
#endif
|
||||
|
||||
tem = f->icon_name;
|
||||
if (!NILP (tem))
|
||||
[win setMiniwindowTitle:
|
||||
|
|
Loading…
Add table
Reference in a new issue