commit 57b8611e7b3b8078a29cc67760f046b1c185f0fa
parent 5e6aeab8fedcf6332f975060dda47597a2b30b26
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 25 Apr 2019 14:24:45 -0400
"Add" "HiDPI" "support"
Diffstat:
6 files changed, 113 insertions(+), 51 deletions(-)
diff --git a/include/view.h b/include/view.h
@@ -19,5 +19,6 @@ void server_new_xdg_surface(struct wl_listener *listener, void *data);
void wio_view_focus(struct wio_view *view, struct wlr_surface *surface);
struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy);
+void wio_view_move(struct wio_view *view, int x, int y);
#endif
diff --git a/input.c b/input.c
@@ -341,8 +341,8 @@ static void handle_button_internal(
y1 = y2;
y2 = _;
}
- server->interactive.view->x = x1 + window_border;
- server->interactive.view->y = y1 + window_border;
+ wio_view_move(server->interactive.view,
+ x1 + window_border, y1 + window_border);
uint32_t width = x2 - x1, height = y2 - y1;
if (width < 100) {
width = 100;
@@ -369,10 +369,9 @@ static void handle_button_internal(
}
break;
case INPUT_STATE_MOVE:
- server->interactive.view->x =
- server->cursor->x - server->interactive.sx;
- server->interactive.view->y =
- server->cursor->y - server->interactive.sy;
+ wio_view_move(server->interactive.view,
+ server->cursor->x - server->interactive.sx,
+ server->cursor->y - server->interactive.sy);
view_end_interactive(server);
break;
case INPUT_STATE_DELETE_SELECT:
diff --git a/main.c b/main.c
@@ -179,6 +179,13 @@ int main(int argc, char **argv) {
server.cursor_mgr = wlr_xcursor_manager_create(NULL, 24);
wlr_xcursor_manager_load(server.cursor_mgr, 1);
+ struct wio_output_config *config;
+ wl_list_for_each(config, &server.output_configs, link) {
+ if (config->scale > 1){
+ wlr_xcursor_manager_load(server.cursor_mgr, config->scale);
+ }
+ }
+
server.cursor_motion.notify = server_cursor_motion;
wl_signal_add(&server.cursor->events.motion, &server.cursor_motion);
server.cursor_motion_absolute.notify = server_cursor_motion_absolute;
diff --git a/meson.build b/meson.build
@@ -21,7 +21,10 @@ add_project_arguments(
language: 'c',
)
+cc = meson.get_compiler('c')
+
cairo = dependency('cairo')
+math = cc.find_library('m')
wlroots = dependency('wlroots', fallback: ['wlroots', 'wlroots'])
wayland_server = dependency('wayland-server')
wayland_protos = dependency('wayland-protocols')
@@ -44,6 +47,7 @@ executable(
include_directories: [wio_inc],
dependencies: [
cairo,
+ math,
server_protos,
wayland_server,
wlroots,
diff --git a/output.c b/output.c
@@ -1,6 +1,7 @@
#define _POSIX_C_SOURCE 200112L
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#include <time.h>
#include <wayland-server.h>
#include <wlr/types/wlr_matrix.h>
@@ -45,6 +46,17 @@ static void render_surface(struct wlr_surface *surface,
wlr_surface_send_frame_done(surface, rdata->when);
}
+static int scale_length(int length, int offset, float scale) {
+ return round((offset + length) * scale) - round(offset * scale);
+}
+
+void scale_box(struct wlr_box *box, float scale) {
+ box->width = scale_length(box->width, box->x, scale);
+ box->height = scale_length(box->height, box->y, scale);
+ box->x = round(box->x * scale);
+ box->y = round(box->y * scale);
+}
+
static void render_menu(struct wio_output *output) {
struct wio_server *server = output->server;
struct wlr_renderer *renderer = server->renderer;
@@ -52,7 +64,8 @@ static void render_menu(struct wio_output *output) {
size_t ntextures =
sizeof(server->menu.inactive_textures) /
sizeof(server->menu.inactive_textures[0]);
- const int border = 3, margin = 4;
+ int scale = output->wlr_output->scale;
+ int border = 3 * scale, margin = 4 * scale;
int text_height = 0, text_width = 0;
for (size_t i = 0; i < ntextures; ++i) {
int width, height;
@@ -60,6 +73,7 @@ static void render_menu(struct wio_output *output) {
// (they probably are)
wlr_texture_get_size(
server->menu.inactive_textures[i], &width, &height);
+ width /= scale, height /= scale;
text_height += height + margin;
if (width >= text_width) {
text_width = width;
@@ -72,29 +86,46 @@ static void render_menu(struct wio_output *output) {
wlr_output_layout_output_coords(
server->output_layout, output->wlr_output, &ox, &oy);
ox += server->menu.x, oy += server->menu.y;
- int scale = output->wlr_output->scale;
- struct wlr_box bg_box = {
- .x = ox * scale,
- .y = oy * scale,
- .width = text_width * scale,
- .height = text_height * scale,
- };
+ struct wlr_box bg_box = { 0 };
+ // Background
+ bg_box.x = ox;
+ bg_box.y = oy;
+ bg_box.width = text_width;
+ bg_box.height = text_height;
+ scale_box(&bg_box, scale);
wlr_render_rect(renderer, &bg_box, menu_unselected,
output->wlr_output->transform_matrix);
+ // Top
+ bg_box.x = ox;
+ bg_box.y = oy;
+ bg_box.width = text_width;
bg_box.height = border;
+ scale_box(&bg_box, scale);
wlr_render_rect(renderer, &bg_box, menu_border,
output->wlr_output->transform_matrix);
- bg_box.width += border;
- bg_box.y = (oy + text_height) * scale;
+ // Bottom
+ bg_box.x = ox;
+ bg_box.y = oy + text_height;
+ bg_box.width = text_width + border;
+ bg_box.height = border;
+ scale_box(&bg_box, scale);
wlr_render_rect(renderer, &bg_box, menu_border,
output->wlr_output->transform_matrix);
- bg_box.y = oy * scale;
- bg_box.height = text_height * scale;
+ // Left
+ bg_box.x = ox;
+ bg_box.y = oy;
bg_box.width = border;
+ bg_box.height = text_height;
+ scale_box(&bg_box, scale);
wlr_render_rect(renderer, &bg_box, menu_border,
output->wlr_output->transform_matrix);
- bg_box.x = (ox + text_width) * scale;
+ // Right
+ bg_box.x = ox + text_width;
+ bg_box.y = oy;
+ bg_box.width = border;
+ bg_box.height = text_height;
+ scale_box(&bg_box, scale);
wlr_render_rect(renderer, &bg_box, menu_border,
output->wlr_output->transform_matrix);
@@ -105,19 +136,22 @@ static void render_menu(struct wio_output *output) {
int width, height;
struct wlr_texture *texture = server->menu.inactive_textures[i];
wlr_texture_get_size(texture, &width, &height);
+ width /= scale, height /= scale;
struct wlr_box box = { 0 };
- box.x = ox - 1 * scale;
- box.y = oy - 1 * scale;
- box.width = (text_width - border) * scale;
- box.height = (height + margin) * scale;
+ box.x = ox - scale /* fudge */;
+ box.y = oy - scale /* fudge */;
+ box.width = text_width - border;
+ box.height = height + margin;
if (wlr_box_contains_point(
&box, server->cursor->x, server->cursor->y)) {
server->menu.selected = i;
texture = server->menu.active_textures[i];
+ scale_box(&box, scale);
wlr_render_rect(renderer, &box, menu_selected,
output->wlr_output->transform_matrix);
} else {
wlr_texture_get_size(texture, &width, &height);
+ width /= scale, height /= scale;
}
box.x = (ox + (text_width / 2 - width / 2)) * scale;
box.y = oy * scale;
@@ -143,9 +177,10 @@ static void render_view_border(struct wlr_renderer *renderer,
} else {
memcpy(color, inactive_border, sizeof(color));
}
+ struct wlr_output *wlr_output = output->wlr_output;
double ox, oy;
- wlr_output_layout_output_coords(
- output->server->output_layout, output->wlr_output, &ox, &oy);
+ wlr_output_layout_output_coords(output->server->output_layout,
+ wlr_output, &ox, &oy);
struct wlr_box borders;
// Top
borders.x = x - window_border;
@@ -154,8 +189,8 @@ static void render_view_border(struct wlr_renderer *renderer,
borders.y += oy;
borders.width = width + window_border * 2;
borders.height = window_border;
- wlr_render_rect(renderer, &borders, color,
- output->wlr_output->transform_matrix);
+ scale_box(&borders, wlr_output->scale);
+ wlr_render_rect(renderer, &borders, color, wlr_output->transform_matrix);
// Right
borders.x = x + width;
borders.y = y - window_border;
@@ -163,8 +198,8 @@ static void render_view_border(struct wlr_renderer *renderer,
borders.y += oy;
borders.width = window_border;
borders.height = height + window_border * 2;
- wlr_render_rect(renderer, &borders, color,
- output->wlr_output->transform_matrix);
+ scale_box(&borders, wlr_output->scale);
+ wlr_render_rect(renderer, &borders, color, wlr_output->transform_matrix);
// Bottom
borders.x = x - window_border;
borders.x += ox;
@@ -172,8 +207,8 @@ static void render_view_border(struct wlr_renderer *renderer,
borders.y += oy;
borders.width = width + window_border * 2;
borders.height = window_border;
- wlr_render_rect(renderer, &borders, color,
- output->wlr_output->transform_matrix);
+ scale_box(&borders, wlr_output->scale);
+ wlr_render_rect(renderer, &borders, color, wlr_output->transform_matrix);
// Left
borders.x = x - window_border;
borders.x += ox;
@@ -181,8 +216,8 @@ static void render_view_border(struct wlr_renderer *renderer,
borders.y += oy;
borders.width = window_border;
borders.height = height + window_border * 2;
- wlr_render_rect(renderer, &borders, color,
- output->wlr_output->transform_matrix);
+ scale_box(&borders, wlr_output->scale);
+ wlr_render_rect(renderer, &borders, color, wlr_output->transform_matrix);
}
static void output_frame(struct wl_listener *listener, void *data) {
@@ -197,10 +232,8 @@ static void output_frame(struct wl_listener *listener, void *data) {
return;
}
- int width, height;
- wlr_output_effective_resolution(output->wlr_output, &width, &height);
- wlr_renderer_begin(renderer, width, height);
-
+ struct wlr_output *wlr_output = output->wlr_output;
+ wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
wlr_renderer_clear(renderer, background);
struct wio_view *view;
@@ -209,7 +242,7 @@ static void output_frame(struct wl_listener *listener, void *data) {
continue;
}
struct render_data rdata = {
- .output = output->wlr_output,
+ .output = wlr_output,
.view = view,
.renderer = renderer,
.when = &now,
@@ -245,9 +278,9 @@ static void output_frame(struct wl_listener *listener, void *data) {
render_menu(output);
}
- wlr_output_render_software_cursors(output->wlr_output, NULL);
+ wlr_output_render_software_cursors(wlr_output, NULL);
wlr_renderer_end(renderer);
- wlr_output_commit(output->wlr_output);
+ wlr_output_commit(wlr_output);
}
void server_new_output(struct wl_listener *listener, void *data) {
@@ -278,19 +311,22 @@ void server_new_output(struct wl_listener *listener, void *data) {
wlr_output_layout_add(server->output_layout, wlr_output,
config->x, config->y);
}
+ bool modeset = false;
if (config->width && config->height
&& !wl_list_empty(&wlr_output->modes)) {
- bool set = false;
struct wlr_output_mode *mode;
wl_list_for_each(mode, &wlr_output->modes, link) {
if (mode->width == config->width
&& mode->height == config->height) {
wlr_output_set_mode(wlr_output, mode);
- set = true;
+ modeset = true;
}
}
- if (!set) {
- mode = wl_container_of(wlr_output->modes.prev, mode, link);
+ }
+ if (!modeset) {
+ struct wlr_output_mode *mode =
+ wlr_output_preferred_mode(wlr_output);
+ if (mode) {
wlr_output_set_mode(wlr_output, mode);
}
}
@@ -301,9 +337,9 @@ void server_new_output(struct wl_listener *listener, void *data) {
wlr_output_set_transform(wlr_output, config->transform);
}
} else {
- if (!wl_list_empty(&wlr_output->modes)) {
- struct wlr_output_mode *mode =
- wl_container_of(wlr_output->modes.prev, mode, link);
+ struct wlr_output_mode *mode =
+ wlr_output_preferred_mode(wlr_output);
+ if (mode) {
wlr_output_set_mode(wlr_output, mode);
}
wlr_output_layout_add_auto(server->output_layout, wlr_output);
diff --git a/view.c b/view.c
@@ -15,10 +15,14 @@ static void xdg_surface_map(struct wl_listener *listener, void *data) {
struct wlr_output_layout_output *layout = wlr_output_layout_get(
server->output_layout, output);
if (view->x == -1 || view->y == -1) {
- view->x = layout->x +
- (output->width / 2 - view->xdg_surface->surface->current.width / 2);
- view->y = layout->y +
- (output->height / 2 - view->xdg_surface->surface->current.height / 2);
+ struct wlr_surface_state *current =
+ &view->xdg_surface->surface->current;
+ wio_view_move(view,
+ layout->x + (output->width / 2 - current->width / 2),
+ layout->y + (output->height / 2 - current->height / 2));
+ } else {
+ // Sends wl_surface_enter
+ wio_view_move(view, view->x, view->y);
}
}
@@ -126,3 +130,14 @@ struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
}
return NULL;
}
+
+void wio_view_move(struct wio_view *view, int x, int y) {
+ view->x = x;
+ view->y = y;
+
+ // Cheating as FUCK because I'm lazy
+ struct wio_output *output;
+ wl_list_for_each(output, &view->server->outputs, link) {
+ wlr_surface_send_enter(view->xdg_surface->surface, output->wlr_output);
+ }
+}