Wayland GNOME: titlebar color now follows system theme
When GNOME system theme is default, the color matches the background color. When it is dark it is dark.
This commit is contained in:
parent
bdfa57039c
commit
1bffe89b5d
17 changed files with 85 additions and 46 deletions
|
|
@ -59,10 +59,10 @@ Detailed list of changes
|
|||
|
||||
- Wayland: Support fractional scales so that there is no wasted drawing at larger scale followed by resizing in the compositor
|
||||
|
||||
- Wayland: Support preferred integer scales
|
||||
|
||||
- Wayland KDE: Support :opt:`background_blur`
|
||||
|
||||
- Wayland GNOME: The window titlebar color now follows the system light/dark color scheme preference, see :opt:`wayland_titlebar_color`
|
||||
|
||||
- Wayland KDE: Fix mouse cursor hiding not working in Plasma 6 (:iss:`7265`)
|
||||
|
||||
- Wayland IME: Fix a bug with handling synthetic keypresses generated by ZMK keyboard + fcitx (:pull:`7283`)
|
||||
|
|
@ -83,6 +83,8 @@ Detailed list of changes
|
|||
|
||||
- Linux: Fix for a regression in 0.32.0 that caused some CJK fonts to not render glyphs (:iss:`7263`)
|
||||
|
||||
- Wayland: Support preferred integer scales
|
||||
|
||||
0.33.1 [2024-03-21]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -1141,3 +1141,5 @@ void _glfwPlatformUpdateTimer(unsigned long long timer_id, monotonic_t interval,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformInputColorScheme(GLFWColorScheme appearance UNUSED) { }
|
||||
|
|
|
|||
|
|
@ -1012,13 +1012,11 @@ - (void)mouseEntered:(NSEvent *)event
|
|||
|
||||
- (void)viewDidChangeEffectiveAppearance
|
||||
{
|
||||
static int appearance = 0;
|
||||
if (_glfw.callbacks.system_color_theme_change) {
|
||||
int new_appearance = glfwGetCurrentSystemColorTheme();
|
||||
if (new_appearance != appearance) {
|
||||
appearance = new_appearance;
|
||||
_glfw.callbacks.system_color_theme_change(appearance);
|
||||
}
|
||||
static GLFWColorScheme appearance = GLFW_COLOR_SCHEME_NO_PREFERENCE;
|
||||
GLFWColorScheme new_appearance = glfwGetCurrentSystemColorTheme();
|
||||
if (new_appearance != appearance) {
|
||||
appearance = new_appearance;
|
||||
_glfwInputColorScheme(appearance);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3143,7 +3141,7 @@ GLFWAPI void glfwCocoaSetWindowChrome(GLFWwindow *w, unsigned int color, bool us
|
|||
[window->ns.object makeFirstResponder:window->ns.view];
|
||||
}}
|
||||
|
||||
GLFWAPI int glfwGetCurrentSystemColorTheme(void) {
|
||||
GLFWAPI GLFWColorScheme glfwGetCurrentSystemColorTheme(void) {
|
||||
int theme_type = 0;
|
||||
NSAppearance *changedAppearance = NSApp.effectiveAppearance;
|
||||
NSAppearanceName newAppearance = [changedAppearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
|
||||
|
|
|
|||
10
glfw/glfw3.h
vendored
10
glfw/glfw3.h
vendored
|
|
@ -540,6 +540,12 @@ typedef enum GLFWMouseButton {
|
|||
} GLFWMouseButton;
|
||||
/*! @} */
|
||||
|
||||
typedef enum GLFWColorScheme {
|
||||
GLFW_COLOR_SCHEME_NO_PREFERENCE = 0,
|
||||
GLFW_COLOR_SCHEME_DARK = 1,
|
||||
GLFW_COLOR_SCHEME_LIGHT = 2
|
||||
} GLFWColorScheme;
|
||||
|
||||
/*! @defgroup joysticks Joysticks
|
||||
* @brief Joystick IDs.
|
||||
*
|
||||
|
|
@ -1426,7 +1432,7 @@ typedef void (* GLFWapplicationclosefun)(int);
|
|||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
typedef void (* GLFWsystemcolorthemechangefun)(int);
|
||||
typedef void (* GLFWsystemcolorthemechangefun)(GLFWColorScheme);
|
||||
|
||||
|
||||
/*! @brief The function pointer type for window content refresh callbacks.
|
||||
|
|
@ -3969,7 +3975,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
|
|||
GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun callback);
|
||||
GLFWAPI GLFWapplicationclosefun glfwSetApplicationCloseCallback(GLFWapplicationclosefun callback);
|
||||
GLFWAPI GLFWsystemcolorthemechangefun glfwSetSystemColorThemeChangeCallback(GLFWsystemcolorthemechangefun callback);
|
||||
GLFWAPI int glfwGetCurrentSystemColorTheme(void);
|
||||
GLFWAPI GLFWColorScheme glfwGetCurrentSystemColorTheme(void);
|
||||
|
||||
/*! @brief Sets the refresh callback for the specified window.
|
||||
*
|
||||
|
|
|
|||
3
glfw/init.c
vendored
3
glfw/init.c
vendored
|
|
@ -34,7 +34,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
// The global variables below comprise all mutable global data in GLFW
|
||||
|
|
@ -382,7 +381,7 @@ GLFWAPI GLFWapplicationclosefun glfwSetApplicationCloseCallback(GLFWapplicationc
|
|||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWapplicationclosefun glfwSetSystemColorThemeChangeCallback(GLFWsystemcolorthemechangefun cbfun)
|
||||
GLFWAPI GLFWsystemcolorthemechangefun glfwSetSystemColorThemeChangeCallback(GLFWsystemcolorthemechangefun cbfun)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(_glfw.callbacks.system_color_theme_change, cbfun);
|
||||
|
|
|
|||
4
glfw/input.c
vendored
4
glfw/input.c
vendored
|
|
@ -448,6 +448,10 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
|
|||
js->hats[hat] = value;
|
||||
}
|
||||
|
||||
void _glfwInputColorScheme(GLFWColorScheme value) {
|
||||
_glfwPlatformInputColorScheme(value);
|
||||
if (_glfw.callbacks.system_color_theme_change) _glfw.callbacks.system_color_theme_change(value);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
|
|
|
|||
2
glfw/internal.h
vendored
2
glfw/internal.h
vendored
|
|
@ -804,6 +804,8 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
|
|||
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, bool entered);
|
||||
int _glfwInputDrop(_GLFWwindow* window, const char *mime, const char *text, size_t sz);
|
||||
void _glfwInputColorScheme(GLFWColorScheme);
|
||||
void _glfwPlatformInputColorScheme(GLFWColorScheme);
|
||||
void _glfwInputJoystick(_GLFWjoystick* js, int event);
|
||||
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value);
|
||||
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value);
|
||||
|
|
|
|||
14
glfw/linux_desktop_settings.c
vendored
14
glfw/linux_desktop_settings.c
vendored
|
|
@ -20,10 +20,10 @@
|
|||
|
||||
static char theme_name[128] = {0};
|
||||
static int theme_size = -1;
|
||||
static uint32_t appearance = 0;
|
||||
static GLFWColorScheme appearance = GLFW_COLOR_SCHEME_NO_PREFERENCE;
|
||||
static bool cursor_theme_changed = false;
|
||||
|
||||
int
|
||||
GLFWColorScheme
|
||||
glfw_current_system_color_theme(void) {
|
||||
return appearance;
|
||||
}
|
||||
|
|
@ -39,8 +39,10 @@ static void
|
|||
process_fdo_setting(const char *key, DBusMessageIter *value) {
|
||||
if (strcmp(key, FDO_APPEARANCE_KEY) == 0) {
|
||||
if (dbus_message_iter_get_arg_type(value) == DBUS_TYPE_UINT32) {
|
||||
dbus_message_iter_get_basic(value, &appearance);
|
||||
if (appearance > 2) appearance = 0;
|
||||
uint32_t val;
|
||||
dbus_message_iter_get_basic(value, &val);
|
||||
if (val > 2) val = 0;
|
||||
appearance = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -159,9 +161,7 @@ on_color_scheme_change(DBusMessage *message) {
|
|||
if (val > 2) val = 0;
|
||||
if (val != appearance) {
|
||||
appearance = val;
|
||||
if (_glfw.callbacks.system_color_theme_change) {
|
||||
_glfw.callbacks.system_color_theme_change(appearance);
|
||||
}
|
||||
_glfwInputColorScheme(appearance);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
2
glfw/linux_desktop_settings.h
vendored
2
glfw/linux_desktop_settings.h
vendored
|
|
@ -12,4 +12,4 @@
|
|||
|
||||
void glfw_initialize_desktop_settings(void);
|
||||
void glfw_current_cursor_theme(const char **theme, int *size);
|
||||
int glfw_current_system_color_theme(void);
|
||||
GLFWColorScheme glfw_current_system_color_theme(void);
|
||||
|
|
|
|||
23
glfw/wl_client_side_decorations.c
vendored
23
glfw/wl_client_side_decorations.c
vendored
|
|
@ -22,8 +22,6 @@
|
|||
#define B(x) ((x) & 0xff)
|
||||
#define SWAP(x, y) do { __typeof__(x) SWAP = x; x = y; y = SWAP; } while (0)
|
||||
|
||||
static const uint32_t passive_bg_color = 0xffeeeeee;
|
||||
static const uint32_t active_bg_color = 0xffdddad6;
|
||||
typedef float kernel_type;
|
||||
|
||||
static void
|
||||
|
|
@ -166,18 +164,19 @@ create_shadow_tile(_GLFWwindow *window) {
|
|||
static void
|
||||
render_title_bar(_GLFWwindow *window, bool to_front_buffer) {
|
||||
const bool is_focused = window->id == _glfw.focusedWindowId;
|
||||
uint32_t bg_color = is_focused ? active_bg_color : passive_bg_color;
|
||||
uint32_t fg_color = is_focused ? 0xff444444 : 0xff888888;
|
||||
if (decs.use_custom_titlebar_color) {
|
||||
uint32_t light_fg = is_focused ? 0xff444444 : 0xff888888, light_bg = is_focused ? 0xffdddad6 : 0xffeeeeee;
|
||||
uint32_t dark_fg = is_focused ? 0xffffffff : 0xffcccccc, dark_bg = is_focused ? 0xff303030 : 0xff242424;
|
||||
uint32_t bg_color = light_bg, fg_color = light_fg;
|
||||
GLFWColorScheme appearance = glfwGetCurrentSystemColorTheme();
|
||||
if (decs.use_custom_titlebar_color || appearance == GLFW_COLOR_SCHEME_NO_PREFERENCE) {
|
||||
bg_color = 0xff000000 | (decs.titlebar_color & 0xffffff);
|
||||
double red = ((bg_color >> 16) & 0xFF) / 255.0;
|
||||
double green = ((bg_color >> 8) & 0xFF) / 255.0;
|
||||
double blue = (bg_color & 0xFF) / 255.0;
|
||||
double luma = 0.2126 * red + 0.7152 * green + 0.0722 * blue;
|
||||
if (luma < 0.5) {
|
||||
fg_color = is_focused ? 0xffeeeeee : 0xff888888;
|
||||
}
|
||||
}
|
||||
if (luma < 0.5) fg_color = dark_fg;
|
||||
if (!decs.use_custom_titlebar_color) bg_color = luma < 0.5 ? dark_bg : light_bg;
|
||||
} else if (appearance == GLFW_COLOR_SCHEME_DARK) { bg_color = dark_bg; fg_color = dark_fg; }
|
||||
uint8_t *output = to_front_buffer ? decs.top.buffer.data.front : decs.top.buffer.data.back;
|
||||
|
||||
// render shadow part
|
||||
|
|
@ -456,9 +455,7 @@ set_csd_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height) {
|
|||
void
|
||||
set_titlebar_color(_GLFWwindow *window, uint32_t color, bool use_system_color) {
|
||||
bool use_custom_color = !use_system_color;
|
||||
if (use_custom_color != decs.use_custom_titlebar_color || color != decs.titlebar_color) {
|
||||
decs.use_custom_titlebar_color = use_custom_color;
|
||||
decs.titlebar_color = color;
|
||||
}
|
||||
decs.use_custom_titlebar_color = use_custom_color;
|
||||
decs.titlebar_color = color;
|
||||
change_csd_title(window);
|
||||
}
|
||||
|
|
|
|||
3
glfw/wl_init.c
vendored
3
glfw/wl_init.c
vendored
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#define _GNU_SOURCE
|
||||
#include "internal.h"
|
||||
#include "wl_client_side_decorations.h"
|
||||
#include "backend_utils.h"
|
||||
#include "linux_desktop_settings.h"
|
||||
#include "../kitty/monotonic.h"
|
||||
|
|
@ -781,7 +782,7 @@ static const struct wl_registry_listener registryListener = {
|
|||
};
|
||||
|
||||
|
||||
GLFWAPI int glfwGetCurrentSystemColorTheme(void) {
|
||||
GLFWAPI GLFWColorScheme glfwGetCurrentSystemColorTheme(void) {
|
||||
return glfw_current_system_color_theme();
|
||||
}
|
||||
|
||||
|
|
|
|||
11
glfw/wl_window.c
vendored
11
glfw/wl_window.c
vendored
|
|
@ -2691,3 +2691,14 @@ GLFWAPI void glfwWaylandSetupLayerShellForNextWindow(GLFWLayerShellConfig c) {
|
|||
if (layer_shell_config_for_next_window.output_name && !layer_shell_config_for_next_window.output_name[0]) layer_shell_config_for_next_window.output_name = NULL;
|
||||
if (layer_shell_config_for_next_window.output_name) layer_shell_config_for_next_window.output_name = strdup(layer_shell_config_for_next_window.output_name);
|
||||
}
|
||||
|
||||
void
|
||||
_glfwPlatformInputColorScheme(GLFWColorScheme appearance UNUSED) {
|
||||
_GLFWwindow* window = _glfw.windowListHead;
|
||||
while (window) {
|
||||
change_csd_title(window);
|
||||
commit_window_surface_if_safe(window);
|
||||
|
||||
window = window->next;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
6
glfw/x11_init.c
vendored
6
glfw/x11_init.c
vendored
|
|
@ -614,10 +614,12 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
|
|||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWAPI int glfwGetCurrentSystemColorTheme(void) {
|
||||
return 0;
|
||||
GLFWAPI GLFWColorScheme glfwGetCurrentSystemColorTheme(void) {
|
||||
return GLFW_COLOR_SCHEME_NO_PREFERENCE;
|
||||
}
|
||||
|
||||
void _glfwPlatformInputColorScheme(GLFWColorScheme appearance UNUSED) { }
|
||||
|
||||
int _glfwPlatformInit(void)
|
||||
{
|
||||
XInitThreads();
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
Iterable,
|
||||
Iterator,
|
||||
List,
|
||||
Literal,
|
||||
Optional,
|
||||
Sequence,
|
||||
Set,
|
||||
|
|
@ -2934,7 +2935,7 @@ def discard_event(self) -> None:
|
|||
def sanitize_url_for_dispay_to_user(self, url: str) -> str:
|
||||
return sanitize_url_for_dispay_to_user(url)
|
||||
|
||||
def on_system_color_scheme_change(self, appearance: int) -> None:
|
||||
def on_system_color_scheme_change(self, appearance: Literal['light', 'dark', 'no_preference']) -> None:
|
||||
log_error('system color theme changed:', appearance)
|
||||
|
||||
@ac('win', '''
|
||||
|
|
|
|||
10
kitty/glfw-wrapper.h
generated
10
kitty/glfw-wrapper.h
generated
|
|
@ -278,6 +278,12 @@ typedef enum GLFWMouseButton {
|
|||
} GLFWMouseButton;
|
||||
/*! @} */
|
||||
|
||||
typedef enum GLFWColorScheme {
|
||||
GLFW_COLOR_SCHEME_NO_PREFERENCE = 0,
|
||||
GLFW_COLOR_SCHEME_DARK = 1,
|
||||
GLFW_COLOR_SCHEME_LIGHT = 2
|
||||
} GLFWColorScheme;
|
||||
|
||||
/*! @defgroup joysticks Joysticks
|
||||
* @brief Joystick IDs.
|
||||
*
|
||||
|
|
@ -1164,7 +1170,7 @@ typedef void (* GLFWapplicationclosefun)(int);
|
|||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
typedef void (* GLFWsystemcolorthemechangefun)(int);
|
||||
typedef void (* GLFWsystemcolorthemechangefun)(GLFWColorScheme);
|
||||
|
||||
|
||||
/*! @brief The function pointer type for window content refresh callbacks.
|
||||
|
|
@ -1997,7 +2003,7 @@ typedef GLFWsystemcolorthemechangefun (*glfwSetSystemColorThemeChangeCallback_fu
|
|||
GFW_EXTERN glfwSetSystemColorThemeChangeCallback_func glfwSetSystemColorThemeChangeCallback_impl;
|
||||
#define glfwSetSystemColorThemeChangeCallback glfwSetSystemColorThemeChangeCallback_impl
|
||||
|
||||
typedef int (*glfwGetCurrentSystemColorTheme_func)(void);
|
||||
typedef GLFWColorScheme (*glfwGetCurrentSystemColorTheme_func)(void);
|
||||
GFW_EXTERN glfwGetCurrentSystemColorTheme_func glfwGetCurrentSystemColorTheme_impl;
|
||||
#define glfwGetCurrentSystemColorTheme glfwGetCurrentSystemColorTheme_impl
|
||||
|
||||
|
|
|
|||
14
kitty/glfw.c
14
kitty/glfw.c
|
|
@ -62,8 +62,15 @@ get_platform_dependent_config_values(void *glfw_window) {
|
|||
}
|
||||
|
||||
static void
|
||||
on_system_color_scheme_change(int appearance) {
|
||||
call_boss(on_system_color_scheme_change, "i", appearance);
|
||||
on_system_color_scheme_change(GLFWColorScheme appearance) {
|
||||
const char *which = NULL;
|
||||
switch (appearance) {
|
||||
case GLFW_COLOR_SCHEME_NO_PREFERENCE: which = "no_preference"; break;
|
||||
case GLFW_COLOR_SCHEME_DARK: which = "dark"; break;
|
||||
case GLFW_COLOR_SCHEME_LIGHT: which = "light"; break;
|
||||
}
|
||||
debug("system color-scheme changed to: %s\n", which);
|
||||
call_boss(on_system_color_scheme_change, "s", which);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -945,7 +952,7 @@ init_window_chrome_state(WindowChromeState *s, color_type active_window_bg, bool
|
|||
#define SET_TCOL(val) \
|
||||
s->use_system_color = false; \
|
||||
switch (val & 0xff) { \
|
||||
case 0: s->use_system_color = true; break; \
|
||||
case 0: s->use_system_color = true; s->color = active_window_bg; break; \
|
||||
case 1: s->color = active_window_bg; break; \
|
||||
default: s->color = val >> 8; break; \
|
||||
}
|
||||
|
|
@ -2265,6 +2272,7 @@ init_glfw(PyObject *m) {
|
|||
ADDC(GLFW_LAYER_SHELL_NONE); ADDC(GLFW_LAYER_SHELL_PANEL); ADDC(GLFW_LAYER_SHELL_BACKGROUND);
|
||||
ADDC(GLFW_FOCUS_NOT_ALLOWED); ADDC(GLFW_FOCUS_EXCLUSIVE); ADDC(GLFW_FOCUS_ON_DEMAND);
|
||||
ADDC(GLFW_EDGE_TOP); ADDC(GLFW_EDGE_BOTTOM); ADDC(GLFW_EDGE_LEFT); ADDC(GLFW_EDGE_RIGHT);
|
||||
ADDC(GLFW_COLOR_SCHEME_NO_PREFERENCE); ADDC(GLFW_COLOR_SCHEME_DARK); ADDC(GLFW_COLOR_SCHEME_LIGHT);
|
||||
|
||||
/* start glfw functional keys (auto generated by gen-key-constants.py do not edit) */
|
||||
ADDC(GLFW_FKEY_ESCAPE);
|
||||
|
|
|
|||
|
|
@ -3275,8 +3275,8 @@
|
|||
opt('wayland_titlebar_color', 'system', option_type='titlebar_color', ctype='uint', long_text='''
|
||||
The color of the kitty window's titlebar on Wayland systems with client
|
||||
side window decorations such as GNOME. A value of :code:`system` means to use
|
||||
the default system color, a value of :code:`background` means to use the
|
||||
background color of the currently active window and finally you can use an
|
||||
the default system colors, a value of :code:`background` means to use the
|
||||
background color of the currently active kitty window and finally you can use an
|
||||
arbitrary color, such as :code:`#12af59` or :code:`red`.
|
||||
'''
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue