mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-24 01:08:10 +02:00
Implement rendering of window control buttons in CSD
They still need to be wired up
This commit is contained in:
2
glfw/glfw3.h
vendored
2
glfw/glfw3.h
vendored
@@ -1785,7 +1785,7 @@ typedef void (* GLFWjoystickfun)(int,int);
|
||||
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
|
||||
typedef void (* GLFWtickcallback)(void*);
|
||||
typedef void (* GLFWactivationcallback)(GLFWwindow *window, const char *token, void *data);
|
||||
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset, size_t right_margin);
|
||||
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset, size_t right_margin, bool is_single_glyph);
|
||||
typedef char* (* GLFWcurrentselectionfun)(void);
|
||||
typedef bool (* GLFWhascurrentselectionfun)(void);
|
||||
typedef void (* GLFWclipboarddatafreefun)(void* data);
|
||||
|
||||
29
glfw/wl_client_side_decorations.c
vendored
29
glfw/wl_client_side_decorations.c
vendored
@@ -164,9 +164,10 @@ 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 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;
|
||||
const uint32_t light_fg = is_focused ? 0xff444444 : 0xff888888, light_bg = is_focused ? 0xffdddad6 : 0xffeeeeee;
|
||||
const uint32_t dark_fg = is_focused ? 0xffffffff : 0xffcccccc, dark_bg = is_focused ? 0xff303030 : 0xff242424;
|
||||
static const uint32_t hover_dark_bg = 0xff444444, hover_light_bg = 0xffcccccc;
|
||||
uint32_t bg_color = light_bg, fg_color = light_fg, hover_bg = hover_light_bg;
|
||||
GLFWColorScheme appearance = glfwGetCurrentSystemColorTheme();
|
||||
if (decs.use_custom_titlebar_color || appearance == GLFW_COLOR_SCHEME_NO_PREFERENCE) {
|
||||
bg_color = 0xff000000 | (decs.titlebar_color & 0xffffff);
|
||||
@@ -174,7 +175,7 @@ render_title_bar(_GLFWwindow *window, bool to_front_buffer) {
|
||||
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 = dark_fg;
|
||||
if (luma < 0.5) { fg_color = dark_fg; hover_bg = hover_dark_bg; }
|
||||
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;
|
||||
@@ -198,12 +199,30 @@ render_title_bar(_GLFWwindow *window, bool to_front_buffer) {
|
||||
}
|
||||
|
||||
// render text part
|
||||
int button_size = (int)roundf(decs.metrics.visible_titlebar_height * decs.for_window_state.fscale);
|
||||
int num_buttons = 1;
|
||||
if (window->wl.wm_capabilities.maximize) num_buttons++;
|
||||
if (window->wl.wm_capabilities.minimize) num_buttons++;
|
||||
output += decs.top.buffer.stride * margin;
|
||||
if (window->wl.title && window->wl.title[0] && _glfw.callbacks.draw_text) {
|
||||
if (_glfw.callbacks.draw_text((GLFWwindow*)window, window->wl.title, fg_color, bg_color, output, decs.top.buffer.width, decs.top.buffer.height - margin, 0, 0, 0)) return;
|
||||
if (_glfw.callbacks.draw_text((GLFWwindow*)window, window->wl.title, fg_color, bg_color, output, decs.top.buffer.width, decs.top.buffer.height - margin, 0, 0, num_buttons * button_size, false)) goto render_buttons;
|
||||
}
|
||||
// rendering of text failed, blank the buffer
|
||||
for (uint32_t *px = (uint32_t*)output, *end = (uint32_t*)(output + decs.top.buffer.size_in_bytes); px < end; px++) *px = bg_color;
|
||||
|
||||
render_buttons:
|
||||
decs.maximize.width = 0; decs.minimize.width = 0; decs.close.width = 0;
|
||||
if (!button_size) return;
|
||||
int left = decs.top.buffer.width - num_buttons * button_size;
|
||||
#define draw(which, text, hover_bg) { \
|
||||
_glfw.callbacks.draw_text((GLFWwindow*)window, text, fg_color, decs.which.hovered ? hover_bg : bg_color, output, decs.top.buffer.width, \
|
||||
decs.top.buffer.height - margin, /*x=*/left, /*y=*/0, /*right_margin=*/decs.top.buffer.width - left - button_size, true); \
|
||||
decs.which.left = left; decs.which.width = button_size; left += button_size; \
|
||||
}
|
||||
if (window->wl.wm_capabilities.minimize) draw(minimize, "🗕", hover_bg);
|
||||
if (window->wl.wm_capabilities.maximize) draw(maximize, "🗖", hover_bg);
|
||||
draw(close, "🗙", 0xffff0000);
|
||||
#undef draw
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
6
glfw/wl_init.c
vendored
6
glfw/wl_init.c
vendored
@@ -675,8 +675,10 @@ static void registryHandleGlobal(void* data UNUSED,
|
||||
}
|
||||
else if (is(xdg_wm_base))
|
||||
{
|
||||
_glfw.wl.wmBase =
|
||||
wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
|
||||
#ifdef XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION
|
||||
version = min(XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION, version);
|
||||
#endif
|
||||
_glfw.wl.wmBase = wl_registry_bind(registry, name, &xdg_wm_base_interface, version);
|
||||
xdg_wm_base_add_listener(_glfw.wl.wmBase, &wmBaseListener, NULL);
|
||||
}
|
||||
else if (is(zxdg_decoration_manager_v1))
|
||||
|
||||
10
glfw/wl_platform.h
vendored
10
glfw/wl_platform.h
vendored
@@ -166,6 +166,7 @@ typedef struct _GLFWwindowWayland
|
||||
struct xdg_surface* surface;
|
||||
struct xdg_toplevel* toplevel;
|
||||
struct zxdg_toplevel_decoration_v1* decoration;
|
||||
struct { int width, height; } top_level_bounds;
|
||||
} xdg;
|
||||
struct wp_fractional_scale_v1 *wp_fractional_scale_v1;
|
||||
struct wp_viewport *wp_viewport;
|
||||
@@ -224,6 +225,10 @@ typedef struct _GLFWwindowWayland
|
||||
int32_t x, y, width, height;
|
||||
} geometry;
|
||||
|
||||
struct {
|
||||
bool hovered;
|
||||
int width, left;
|
||||
} minimize, maximize, close;
|
||||
struct {
|
||||
uint32_t *data;
|
||||
size_t for_decoration_size, stride, segments, corner_size;
|
||||
@@ -244,6 +249,11 @@ typedef struct _GLFWwindowWayland
|
||||
int32_t width, height;
|
||||
} user_requested_content_size;
|
||||
|
||||
struct {
|
||||
bool minimize, maximize, fullscreen, window_menu;
|
||||
} wm_capabilities;
|
||||
|
||||
|
||||
bool maximize_on_first_show;
|
||||
// counters for ignoring axis events following axis_discrete events in the
|
||||
// same frame along the same axis
|
||||
|
||||
37
glfw/wl_window.c
vendored
37
glfw/wl_window.c
vendored
@@ -696,9 +696,42 @@ static void xdgToplevelHandleClose(void* data,
|
||||
_glfwInputWindowCloseRequest(window);
|
||||
}
|
||||
|
||||
#if defined(XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION)
|
||||
static void
|
||||
xdg_toplevel_wm_capabilities(void *data, struct xdg_toplevel *xdg_toplevel UNUSED, struct wl_array *caps) {
|
||||
_GLFWwindow *window = data;
|
||||
#define c (window->wl.wm_capabilities)
|
||||
memset(&c, 0, sizeof(c));
|
||||
|
||||
enum xdg_toplevel_wm_capabilities *cap;
|
||||
wl_array_for_each(cap, caps) {
|
||||
switch (*cap) {
|
||||
case XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE: c.maximize = true; break;
|
||||
case XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE: c.minimize = true; break;
|
||||
case XDG_TOPLEVEL_WM_CAPABILITIES_WINDOW_MENU: c.window_menu = true; break;
|
||||
case XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN: c.fullscreen = true; break;
|
||||
}
|
||||
}
|
||||
debug("Compositor top-level capabilities: maximize=%d minimize=%d window_menu=%d fullscreen=%d\n",
|
||||
c.maximize, c.minimize, c.window_menu, c.fullscreen);
|
||||
#undef c
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
xdg_toplevel_configure_bounds(void *data, struct xdg_toplevel *xdg_toplevel UNUSED, int32_t width, int32_t height) {
|
||||
_GLFWwindow *window = data;
|
||||
window->wl.xdg.top_level_bounds.width = width;
|
||||
window->wl.xdg.top_level_bounds.height = height;
|
||||
}
|
||||
|
||||
static const struct xdg_toplevel_listener xdgToplevelListener = {
|
||||
xdgToplevelHandleConfigure,
|
||||
xdgToplevelHandleClose
|
||||
.configure = xdgToplevelHandleConfigure,
|
||||
.close = xdgToplevelHandleClose,
|
||||
#ifdef XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION
|
||||
.configure_bounds = xdg_toplevel_configure_bounds,
|
||||
.wm_capabilities = xdg_toplevel_wm_capabilities,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void
|
||||
|
||||
Reference in New Issue
Block a user