mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-10-26 15:13:22 +03:00
Implement support for preferred buffer scale
This commit is contained in:
parent
55115058d2
commit
83468535dd
8
glfw/wl_client_side_decorations.c
vendored
8
glfw/wl_client_side_decorations.c
vendored
@ -282,7 +282,7 @@ render_edges(_GLFWwindow *window) {
|
||||
|
||||
static bool
|
||||
create_shm_buffers(_GLFWwindow* window) {
|
||||
const unsigned scale = window->wl.integer_scale >= 1 ? window->wl.integer_scale : 1;
|
||||
const unsigned scale = _glfwWaylandIntegerWindowScale(window);
|
||||
|
||||
const size_t vertical_width = decs.metrics.width, vertical_height = window->wl.height + decs.metrics.top;
|
||||
const size_t horizontal_height = decs.metrics.width, horizontal_width = window->wl.width + 2 * decs.metrics.width;
|
||||
@ -371,7 +371,7 @@ ensure_csd_resources(_GLFWwindow *window) {
|
||||
const bool size_changed = (
|
||||
decs.for_window_state.width != window->wl.width ||
|
||||
decs.for_window_state.height != window->wl.height ||
|
||||
decs.for_window_state.scale != window->wl.integer_scale ||
|
||||
decs.for_window_state.scale != _glfwWaylandIntegerWindowScale(window) ||
|
||||
!decs.mapping.data
|
||||
);
|
||||
const bool needs_update = focus_changed || size_changed || !decs.left.surface || decs.buffer_destroyed;
|
||||
@ -384,7 +384,7 @@ ensure_csd_resources(_GLFWwindow *window) {
|
||||
decs.buffer_destroyed = false;
|
||||
}
|
||||
|
||||
int32_t x, y, scale = window->wl.integer_scale < 1 ? 1 : window->wl.integer_scale;
|
||||
int32_t x, y, scale = _glfwWaylandIntegerWindowScale(window);
|
||||
x = 0; y = -decs.metrics.top;
|
||||
if (!decs.top.surface) create_csd_surfaces(window, &decs.top);
|
||||
position_csd_surface(&decs.top, x, y, scale);
|
||||
@ -409,7 +409,7 @@ ensure_csd_resources(_GLFWwindow *window) {
|
||||
|
||||
decs.for_window_state.width = window->wl.width;
|
||||
decs.for_window_state.height = window->wl.height;
|
||||
decs.for_window_state.scale = window->wl.integer_scale;
|
||||
decs.for_window_state.scale = _glfwWaylandIntegerWindowScale(window);
|
||||
decs.for_window_state.focused = is_focused;
|
||||
return true;
|
||||
}
|
||||
|
11
glfw/wl_init.c
vendored
11
glfw/wl_init.c
vendored
@ -132,7 +132,7 @@ static void setCursor(GLFWCursorShape shape, _GLFWwindow* window)
|
||||
struct wl_cursor* cursor;
|
||||
struct wl_cursor_image* image;
|
||||
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
||||
const int scale = window->wl.integer_scale;
|
||||
const int scale = _glfwWaylandIntegerWindowScale(window);
|
||||
|
||||
struct wl_cursor_theme *theme = glfw_wlc_theme_for_scale(scale);
|
||||
if (!theme) return;
|
||||
@ -632,10 +632,13 @@ static void registryHandleGlobal(void* data UNUSED,
|
||||
#define is(x) strcmp(interface, x##_interface.name) == 0
|
||||
if (is(wl_compositor))
|
||||
{
|
||||
#ifdef WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION
|
||||
_glfw.wl.compositorVersion = min(WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION, version);
|
||||
_glfw.wl.has_preferred_buffer_scale = _glfw.wl.compositorVersion >= WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION;
|
||||
#else
|
||||
_glfw.wl.compositorVersion = min(3, version);
|
||||
_glfw.wl.compositor =
|
||||
wl_registry_bind(registry, name, &wl_compositor_interface,
|
||||
_glfw.wl.compositorVersion);
|
||||
#endif
|
||||
_glfw.wl.compositor = wl_registry_bind(registry, name, &wl_compositor_interface, _glfw.wl.compositorVersion);
|
||||
}
|
||||
else if (is(wl_subcompositor))
|
||||
{
|
||||
|
4
glfw/wl_platform.h
vendored
4
glfw/wl_platform.h
vendored
@ -174,7 +174,7 @@ typedef struct _GLFWwindowWayland
|
||||
|
||||
// We need to track the monitors the window spans on to calculate the
|
||||
// optimal scaling factor.
|
||||
int integer_scale;
|
||||
struct { uint32_t deduced, preferred; } integer_scale;
|
||||
uint32_t fractional_scale;
|
||||
bool initial_scale_notified;
|
||||
_GLFWmonitor** monitors;
|
||||
@ -343,6 +343,7 @@ typedef struct _GLFWlibraryWayland
|
||||
EventLoopData eventLoopData;
|
||||
size_t dataOffersCounter;
|
||||
_GLFWWaylandDataOffer dataOffers[8];
|
||||
bool has_preferred_buffer_scale;
|
||||
} _GLFWlibraryWayland;
|
||||
|
||||
// Wayland-specific per-monitor data
|
||||
@ -380,6 +381,7 @@ void _glfwWaylandAfterBufferSwap(_GLFWwindow *window);
|
||||
void _glfwSetupWaylandDataDevice(void);
|
||||
void _glfwSetupWaylandPrimarySelectionDevice(void);
|
||||
float _glfwWaylandWindowScale(_GLFWwindow*);
|
||||
int _glfwWaylandIntegerWindowScale(_GLFWwindow*);
|
||||
void animateCursorImage(id_type timer_id, void *data);
|
||||
struct wl_cursor* _glfwLoadCursor(GLFWCursorShape, struct wl_cursor_theme*);
|
||||
void destroy_data_offer(_GLFWWaylandDataOffer*);
|
||||
|
6
glfw/wl_text_input.c
vendored
6
glfw/wl_text_input.c
vendored
@ -172,8 +172,10 @@ _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
|
||||
commit();
|
||||
break;
|
||||
case GLFW_IME_UPDATE_CURSOR_POSITION: {
|
||||
const int scale = w->wl.integer_scale;
|
||||
const int left = ev->cursor.left / scale, top = ev->cursor.top / scale, width = ev->cursor.width / scale, height = ev->cursor.height / scale;
|
||||
const float scale = _glfwWaylandWindowScale(w);
|
||||
#define s(x) (int)roundf((x) / scale)
|
||||
const int left = s(ev->cursor.left), top = s(ev->cursor.top), width = s(ev->cursor.width), height = s(ev->cursor.height);
|
||||
#undef s
|
||||
if (left != last_cursor_left || top != last_cursor_top || width != last_cursor_width || height != last_cursor_height) {
|
||||
last_cursor_left = left;
|
||||
last_cursor_top = top;
|
||||
|
85
glfw/wl_window.c
vendored
85
glfw/wl_window.c
vendored
@ -206,7 +206,7 @@ setCursorImage(_GLFWwindow* window, bool on_theme_change) {
|
||||
struct wl_cursor_image* image = NULL;
|
||||
struct wl_buffer* buffer = NULL;
|
||||
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
||||
const int scale = window->wl.integer_scale;
|
||||
const int scale = _glfwWaylandIntegerWindowScale(window);
|
||||
if (!_glfw.wl.pointer) return;
|
||||
|
||||
if (cursorWayland->scale < 0) {
|
||||
@ -263,9 +263,9 @@ setCursorImage(_GLFWwindow* window, bool on_theme_change) {
|
||||
|
||||
static bool
|
||||
checkScaleChange(_GLFWwindow* window) {
|
||||
int scale = 1;
|
||||
if (window->wl.fractional_scale || window->wl.integer_scale.preferred) return false;
|
||||
unsigned int scale = 1, monitorScale;
|
||||
int i;
|
||||
int monitorScale;
|
||||
|
||||
// Check if we will be able to set the buffer scale or not.
|
||||
if (_glfw.wl.compositorVersion < 3)
|
||||
@ -281,14 +281,13 @@ checkScaleChange(_GLFWwindow* window) {
|
||||
if (window->wl.monitorsCount < 1 && _glfw.monitorCount > 0) {
|
||||
// The window has not yet been assigned to any monitors, use the primary monitor
|
||||
_GLFWmonitor *m = _glfw.monitors[0];
|
||||
if (m && m->wl.scale > scale) scale = m->wl.scale;
|
||||
if (m && m->wl.scale > (int)scale) scale = m->wl.scale;
|
||||
}
|
||||
|
||||
// Only change the framebuffer size if the scale changed.
|
||||
if (scale != window->wl.integer_scale && !window->wl.fractional_scale)
|
||||
if (scale != window->wl.integer_scale.deduced && !window->wl.fractional_scale)
|
||||
{
|
||||
window->wl.integer_scale = scale;
|
||||
wl_surface_set_buffer_scale(window->wl.surface, scale);
|
||||
window->wl.integer_scale.deduced = scale;
|
||||
setCursorImage(window, false);
|
||||
return true;
|
||||
}
|
||||
@ -323,9 +322,16 @@ static void setOpaqueRegion(_GLFWwindow* window, bool commit_surface)
|
||||
wl_region_destroy(region);
|
||||
}
|
||||
|
||||
int
|
||||
_glfwWaylandIntegerWindowScale(_GLFWwindow *window) {
|
||||
int ans = (window->wl.integer_scale.preferred) ? window->wl.integer_scale.preferred : window->wl.integer_scale.deduced;
|
||||
if (ans < 1) ans = 1;
|
||||
return ans;
|
||||
}
|
||||
|
||||
float
|
||||
_glfwWaylandWindowScale(_GLFWwindow *window) {
|
||||
float ans = window->wl.integer_scale;
|
||||
float ans = _glfwWaylandIntegerWindowScale(window);
|
||||
if (window->wl.fractional_scale) ans = window->wl.fractional_scale / 120.f;
|
||||
return ans;
|
||||
}
|
||||
@ -363,6 +369,16 @@ clipboard_mime(void) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void
|
||||
apply_scale_changes(_GLFWwindow *window, bool resize_framebuffer, bool update_csd) {
|
||||
float scale = _glfwWaylandWindowScale(window);
|
||||
if (resize_framebuffer) resizeFramebuffer(window);
|
||||
_glfwInputWindowContentScale(window, scale, scale);
|
||||
if (update_csd) ensure_csd_resources(window);
|
||||
int buffer_scale = window->wl.fractional_scale ? 1 : (int)scale;
|
||||
wl_surface_set_buffer_scale(window->wl.surface, buffer_scale);
|
||||
}
|
||||
|
||||
static bool
|
||||
dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, int32_t height) {
|
||||
bool size_changed = width != window->wl.width || height != window->wl.height;
|
||||
@ -375,9 +391,8 @@ dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, int32_t height
|
||||
}
|
||||
|
||||
if (scale_changed) {
|
||||
debug("Scale changed to %d in dispatchChangesAfterConfigure\n", window->wl.integer_scale);
|
||||
if (!size_changed) resizeFramebuffer(window);
|
||||
_glfwInputWindowContentScale(window, window->wl.integer_scale, window->wl.integer_scale);
|
||||
debug("Scale changed to %.2f in dispatchChangesAfterConfigure\n", _glfwWaylandWindowScale(window));
|
||||
apply_scale_changes(window, !size_changed, false);
|
||||
}
|
||||
|
||||
_glfwInputWindowDamage(window);
|
||||
@ -429,10 +444,8 @@ static void surfaceHandleEnter(void *data,
|
||||
window->wl.monitors[window->wl.monitorsCount++] = monitor;
|
||||
|
||||
if (checkScaleChange(window)) {
|
||||
debug("Scale changed to %d in surface enter event\n", window->wl.integer_scale);
|
||||
resizeFramebuffer(window);
|
||||
_glfwInputWindowContentScale(window, window->wl.integer_scale, window->wl.integer_scale);
|
||||
ensure_csd_resources(window);
|
||||
debug("Scale changed to %.2f in surfaceHandleEnter\n", _glfwWaylandWindowScale(window));
|
||||
apply_scale_changes(window, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,16 +468,35 @@ static void surfaceHandleLeave(void *data,
|
||||
window->wl.monitors[--window->wl.monitorsCount] = NULL;
|
||||
|
||||
if (checkScaleChange(window)) {
|
||||
debug("Scale changed to %d in surface leave event\n", window->wl.integer_scale);
|
||||
resizeFramebuffer(window);
|
||||
_glfwInputWindowContentScale(window, window->wl.integer_scale, window->wl.integer_scale);
|
||||
ensure_csd_resources(window);
|
||||
debug("Scale changed to %.2f in surfaceHandleLeave\n", _glfwWaylandWindowScale(window));
|
||||
apply_scale_changes(window, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION
|
||||
static void
|
||||
surface_preferred_buffer_scale(void *data, struct wl_surface *surface UNUSED, int32_t scale) {
|
||||
_GLFWwindow* window = data;
|
||||
if ((int)window->wl.integer_scale.preferred == scale) return;
|
||||
debug("Preferred integer buffer scale changed to: %d\n", scale);
|
||||
window->wl.integer_scale.preferred = scale;
|
||||
if (!window->wl.fractional_scale) apply_scale_changes(window, true, true);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_preferred_buffer_transform(void *data, struct wl_surface *surface, uint32_t transform) {
|
||||
(void)data; (void)surface; (void)transform;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static const struct wl_surface_listener surfaceListener = {
|
||||
surfaceHandleEnter,
|
||||
surfaceHandleLeave
|
||||
.enter = surfaceHandleEnter,
|
||||
.leave = surfaceHandleLeave,
|
||||
#ifdef WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION
|
||||
.preferred_buffer_scale = &surface_preferred_buffer_scale,
|
||||
.preferred_buffer_transform = &surface_preferred_buffer_transform,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void
|
||||
@ -473,12 +505,7 @@ fractional_scale_preferred_scale(void *data, struct wp_fractional_scale_v1 *wp_f
|
||||
if (scale == window->wl.fractional_scale) return;
|
||||
debug("Fractional scale requested: %u/120 = %.2f\n", scale, scale / 120.);
|
||||
window->wl.fractional_scale = scale;
|
||||
resizeFramebuffer(window);
|
||||
inform_compositor_of_window_geometry(window, "FractionalScale");
|
||||
wl_surface_set_buffer_scale(window->wl.surface, 1);
|
||||
float fscale = scale / 120.f;
|
||||
_glfwInputWindowContentScale(window, fscale, fscale);
|
||||
ensure_csd_resources(window);
|
||||
apply_scale_changes(window, true, true);
|
||||
}
|
||||
|
||||
static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
|
||||
@ -517,6 +544,9 @@ static bool createSurface(_GLFWwindow* window,
|
||||
wp_fractional_scale_v1_add_listener(window->wl.wp_fractional_scale_v1, &fractional_scale_listener, window);
|
||||
}
|
||||
|
||||
window->wl.integer_scale.deduced = scale;
|
||||
if (_glfw.wl.has_preferred_buffer_scale) { scale = 1; window->wl.integer_scale.preferred = 1; }
|
||||
|
||||
debug("Creating window at size: %dx%d and scale %d\n", wndconfig->width, wndconfig->height, scale);
|
||||
window->wl.native = wl_egl_window_create(window->wl.surface, wndconfig->width * scale, wndconfig->height * scale);
|
||||
if (!window->wl.native)
|
||||
@ -527,7 +557,6 @@ static bool createSurface(_GLFWwindow* window,
|
||||
window->wl.user_requested_content_size.width = wndconfig->width;
|
||||
window->wl.user_requested_content_size.height = wndconfig->height;
|
||||
|
||||
window->wl.integer_scale = scale;
|
||||
|
||||
if (!window->wl.transparent)
|
||||
setOpaqueRegion(window, false);
|
||||
|
Loading…
Reference in New Issue
Block a user