]> git.eshelyaron.com Git - emacs.git/commitdiff
Add ability to change macOS WM theme (bug#27973)
authorAlan Third <alan@idiocy.org>
Sun, 20 Aug 2017 20:14:47 +0000 (21:14 +0100)
committerAlan Third <alan@idiocy.org>
Wed, 23 Aug 2017 18:57:00 +0000 (19:57 +0100)
* 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.

doc/lispref/frames.texi
src/frame.c
src/frame.h
src/nsfns.m
src/nsterm.h
src/nsterm.m

index b430f7c6fadcb695e796d231fb3523f70d504386..6431bbdedb979a360329cec6dd6fec6147ad8058 100644 (file)
@@ -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
 
 
index 1e5e4bbdb48d3ac23ffd97a453856c344da1b147..5099f75be4d9d6e1d6b7dcebe86f462f1d474820 100644 (file)
@@ -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");
index 154dc9a3bb4e8f24e582aa52735131eba7b936fe..4b7e448b54364f9a882cca548b54565e8c6950f0 100644 (file)
@@ -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)
index e19e4e2641a41a62d526cec85e5a99a20e344c21..b00441eb79f7aeb110c576f4c9e97d9aa6a1491f 100644 (file)
@@ -985,6 +985,10 @@ frame_parm_handler ns_frame_parm_handlers[] =
   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 @@ This function is an internal primitive--use `make-frame' instead.  */)
   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 @@ syms_of_nsfns (void)
   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.
index 0ac8043e26422a055a07c4f0234c239427b12470..65b7a0347acad9cdb4de528cee45abb8aab31fdf 100644 (file)
@@ -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);
index 95092b29c894be63c1d42ddba2963505735c6d95..22f8efd6b968af24fa9e9422618609af9d916134 100644 (file)
@@ -2036,6 +2036,58 @@ x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
     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 @@ not_in_argv (NSString *arg)
   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: