mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
Add screen magnifier
This adds a screen magnifier which can be controlled with the `ZoomIn` / `ZoomOut` and `ToggleMagnify` actions. It scales up part of the rendered framebuffer so the magnification may end up looking blurry depending on the magnification scale. PR #1774
This commit is contained in:
parent
ad15c0474d
commit
8ba066a1a5
13 changed files with 473 additions and 1 deletions
|
|
@ -264,6 +264,18 @@ Actions are used in menus and keyboard/mouse bindings.
|
|||
decorations (including those for which the server-side titlebar has been
|
||||
hidden) are not eligible for shading.
|
||||
|
||||
*<action name="ToggleMagnify">*
|
||||
Toggle the screen magnifier on or off at the last magnification level
|
||||
used.
|
||||
|
||||
*<action name="ZoomIn">*++
|
||||
*<action name="ZoomOut">*
|
||||
Increase or decrease the magnification level for the screen magnifier.
|
||||
If the magnifier is currently off, ZoomIn will enable it at the lowest
|
||||
magnification, equal to (1 + the magnifier increment set in the theme).
|
||||
If the magnifier is on and at the lowest magnification, ZoomOut will
|
||||
turn it off.
|
||||
|
||||
*<action name="None" />*
|
||||
If used as the only action for a binding: clear an earlier defined
|
||||
binding.
|
||||
|
|
|
|||
|
|
@ -909,6 +909,39 @@ situation.
|
|||
option has been exposed for unusual use-cases. It is equivalent to
|
||||
Openbox's `<hideDelay>`. Default is 250 ms.
|
||||
|
||||
## MAGNIFIER
|
||||
|
||||
```
|
||||
<magnifier>
|
||||
<width>400</width>
|
||||
<height>400</height>
|
||||
<initScale>2</initScale>
|
||||
<increment>0.2</increment>
|
||||
<useFilter>true</useFilter>
|
||||
</magnifier>
|
||||
```
|
||||
|
||||
*<magnifier><width>*
|
||||
Width of magnifier window in pixels. Default is 400.
|
||||
Set to -1 to use fullscreen magnifier.
|
||||
|
||||
*<magnifier><height>*
|
||||
Height of magnifier window in pixels. Default is 400.
|
||||
Set to -1 to use fullscreen magnifier.
|
||||
|
||||
*<magnifier><initScale>*
|
||||
Initial number of times by which magnified image is scaled. Value
|
||||
is the default at boot; can be modified at run-time in a keyboard
|
||||
or mouse binding by calling 'ZoomIn' or 'ZoomOut'. Default is x2.0.
|
||||
|
||||
*<magnifier><increment>*
|
||||
Step by which magnification changes on each call to 'ZoomIn' or
|
||||
'ZoomOut'. Default is 0.2.
|
||||
|
||||
*<magnifier><useFilter>* [yes|no|default]
|
||||
Whether to apply a bilinear filter to the magnified image, or
|
||||
just to use nearest-neighbour. Default is true - bilinear filtered.
|
||||
|
||||
## ENVIRONMENT VARIABLES
|
||||
|
||||
*XCURSOR_THEME* and *XCURSOR_SIZE* are supported to set cursor theme
|
||||
|
|
|
|||
|
|
@ -277,6 +277,12 @@ elements are not listed here, but are supported.
|
|||
*window.inactive.border.color*. This is obsolete, but supported for
|
||||
backward compatibility as some themes still contain it.
|
||||
|
||||
*magnifier.border.width*
|
||||
Width of magnifier window border in pixels. Default is 1.
|
||||
|
||||
*magnifier.border.color*
|
||||
Color of the magnfier window border. Default is #ff0000 (red).
|
||||
|
||||
# BUTTONS
|
||||
|
||||
The images used for the titlebar icons are referred to as buttons.
|
||||
|
|
|
|||
|
|
@ -589,4 +589,23 @@
|
|||
<menu>
|
||||
<ignoreButtonReleasePeriod>250</ignoreButtonReleasePeriod>
|
||||
</menu>
|
||||
|
||||
<!--
|
||||
Magnifier settings
|
||||
'width' sets the width in pixels of the magnifier window.
|
||||
'height' sets the height in pixels of the magnifier window.
|
||||
'initScale' sets the initial magnification factor at boot.
|
||||
'increment' sets the amount by which the magnification factor
|
||||
changes when 'ZoomIn' or 'ZoomOut' are called.
|
||||
'useFilter' sets whether to use a bilinear filter on the magnified
|
||||
output or simply to take nearest pixel.
|
||||
-->
|
||||
<magnifier>
|
||||
<width>400</width>
|
||||
<height>400</height>
|
||||
<initScale>2.0</initScale>
|
||||
<increment>0.2</increment>
|
||||
<useFilter>true</useFilter>
|
||||
</magnifier>
|
||||
|
||||
</labwc_config>
|
||||
|
|
|
|||
|
|
@ -140,6 +140,13 @@ struct rcxml {
|
|||
|
||||
/* Menu */
|
||||
unsigned int menu_ignore_button_release_period;
|
||||
|
||||
/* Magnifier */
|
||||
int mag_width;
|
||||
int mag_height;
|
||||
float mag_scale;
|
||||
float mag_increment;
|
||||
bool mag_filter;
|
||||
};
|
||||
|
||||
extern struct rcxml rc;
|
||||
|
|
|
|||
23
include/magnifier.h
Normal file
23
include/magnifier.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef LABWC_MAGNIFIER_H
|
||||
#define LABWC_MAGNIFIER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <wayland-server-core.h>
|
||||
|
||||
struct server;
|
||||
struct output;
|
||||
|
||||
enum magnify_dir {
|
||||
MAGNIFY_INCREASE,
|
||||
MAGNIFY_DECREASE
|
||||
};
|
||||
|
||||
void magnify_toggle(struct server *server);
|
||||
void magnify_set_scale(struct server *server, enum magnify_dir dir);
|
||||
bool output_wants_magnification(struct output *output);
|
||||
void magnify(struct output *output, struct wlr_buffer *output_buffer,
|
||||
struct wlr_box *damage);
|
||||
bool is_magnify_on(void);
|
||||
|
||||
#endif /* LABWC_MAGNIFIER_H */
|
||||
|
|
@ -139,6 +139,10 @@ struct theme {
|
|||
|
||||
/* not set in rc.xml/themerc, but derived from font & padding_height */
|
||||
int osd_window_switcher_item_height;
|
||||
|
||||
/* magnifier */
|
||||
float mag_border_color[4];
|
||||
int mag_border_width;
|
||||
};
|
||||
|
||||
struct server;
|
||||
|
|
|
|||
16
src/action.c
16
src/action.c
|
|
@ -15,6 +15,7 @@
|
|||
#include "common/string-helpers.h"
|
||||
#include "debug.h"
|
||||
#include "labwc.h"
|
||||
#include "magnifier.h"
|
||||
#include "menu/menu.h"
|
||||
#include "osd.h"
|
||||
#include "output-virtual.h"
|
||||
|
|
@ -110,6 +111,9 @@ enum action_type {
|
|||
ACTION_TYPE_SHADE,
|
||||
ACTION_TYPE_UNSHADE,
|
||||
ACTION_TYPE_TOGGLE_SHADE,
|
||||
ACTION_TYPE_TOGGLE_MAGNIFY,
|
||||
ACTION_TYPE_ZOOM_IN,
|
||||
ACTION_TYPE_ZOOM_OUT
|
||||
};
|
||||
|
||||
const char *action_names[] = {
|
||||
|
|
@ -163,6 +167,9 @@ const char *action_names[] = {
|
|||
"Shade",
|
||||
"Unshade",
|
||||
"ToggleShade",
|
||||
"ToggleMagnify",
|
||||
"ZoomIn",
|
||||
"ZoomOut",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -1046,6 +1053,15 @@ actions_run(struct view *activator, struct server *server,
|
|||
view_set_shade(view, false);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_TOGGLE_MAGNIFY:
|
||||
magnify_toggle(server);
|
||||
break;
|
||||
case ACTION_TYPE_ZOOM_IN:
|
||||
magnify_set_scale(server, MAGNIFY_INCREASE);
|
||||
break;
|
||||
case ACTION_TYPE_ZOOM_OUT:
|
||||
magnify_set_scale(server, MAGNIFY_DECREASE);
|
||||
break;
|
||||
case ACTION_TYPE_INVALID:
|
||||
wlr_log(WLR_ERROR, "Not executing unknown action");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "common/scene-helpers.h"
|
||||
#include "magnifier.h"
|
||||
|
||||
struct wlr_surface *
|
||||
lab_wlr_surface_from_node(struct wlr_scene_node *node)
|
||||
|
|
@ -44,16 +45,29 @@ lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output)
|
|||
assert(scene_output);
|
||||
struct wlr_output *wlr_output = scene_output->output;
|
||||
struct wlr_output_state *state = &wlr_output->pending;
|
||||
struct output *output = wlr_output->data;
|
||||
bool wants_magnification = output_wants_magnification(output);
|
||||
static bool last_mag = false;
|
||||
|
||||
if (!wlr_output->needs_frame && !pixman_region32_not_empty(
|
||||
&scene_output->damage_ring.current)) {
|
||||
&scene_output->damage_ring.current) && !wants_magnification
|
||||
&& last_mag != is_magnify_on()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
last_mag = is_magnify_on();
|
||||
|
||||
if (!wlr_scene_output_build_state(scene_output, state, NULL)) {
|
||||
wlr_log(WLR_ERROR, "Failed to build output state for %s",
|
||||
wlr_output->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct wlr_box additional_damage = {0};
|
||||
if (state->buffer && is_magnify_on()) {
|
||||
magnify(output, state->buffer, &additional_damage);
|
||||
}
|
||||
|
||||
if (!wlr_output_commit(wlr_output)) {
|
||||
wlr_log(WLR_INFO, "Failed to commit output %s",
|
||||
wlr_output->name);
|
||||
|
|
@ -66,5 +80,9 @@ lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output)
|
|||
* again.
|
||||
*/
|
||||
wlr_damage_ring_rotate(&scene_output->damage_ring);
|
||||
|
||||
if (!wlr_box_empty(&additional_damage)) {
|
||||
wlr_damage_ring_add_box(&scene_output->damage_ring, &additional_damage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1036,6 +1036,16 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
}
|
||||
} else if (!strcasecmp(nodename, "ignoreButtonReleasePeriod.menu")) {
|
||||
rc.menu_ignore_button_release_period = atoi(content);
|
||||
} else if (!strcasecmp(nodename, "width.magnifier")) {
|
||||
rc.mag_width = atoi(content);
|
||||
} else if (!strcasecmp(nodename, "height.magnifier")) {
|
||||
rc.mag_height = atoi(content);
|
||||
} else if (!strcasecmp(nodename, "initScale.magnifier")) {
|
||||
set_float(content, &rc.mag_scale);
|
||||
} else if (!strcasecmp(nodename, "increment.magnifier")) {
|
||||
set_float(content, &rc.mag_increment);
|
||||
} else if (!strcasecmp(nodename, "useFilter.magnifier")) {
|
||||
set_bool(content, &rc.mag_filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1242,6 +1252,12 @@ rcxml_init(void)
|
|||
rc.workspace_config.min_nr_workspaces = 1;
|
||||
|
||||
rc.menu_ignore_button_release_period = 250;
|
||||
|
||||
rc.mag_width = 400;
|
||||
rc.mag_height = 400;
|
||||
rc.mag_scale = 2.0;
|
||||
rc.mag_increment = 0.2;
|
||||
rc.mag_filter = true;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1468,6 +1484,10 @@ post_processing(void)
|
|||
wlr_log(WLR_INFO, "load default window switcher fields");
|
||||
load_default_window_switcher_fields();
|
||||
}
|
||||
|
||||
if (rc.mag_scale <= 0.0) {
|
||||
rc.mag_scale = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
302
src/magnifier.c
Normal file
302
src/magnifier.c
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <assert.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include "magnifier.h"
|
||||
#include "labwc.h"
|
||||
#include "theme.h"
|
||||
#include "common/macros.h"
|
||||
|
||||
bool magnify_on;
|
||||
double mag_scale = 0.0;
|
||||
|
||||
#define CLAMP(in, lower, upper) MAX(MIN(in, upper), lower)
|
||||
|
||||
void
|
||||
magnify(struct output *output, struct wlr_buffer *output_buffer, struct wlr_box *damage)
|
||||
{
|
||||
int width, height;
|
||||
double x, y;
|
||||
struct wlr_box border_box, dst_box;
|
||||
struct wlr_fbox src_box;
|
||||
bool fullscreen = false;
|
||||
|
||||
/* Reuse a single scratch buffer */
|
||||
static struct wlr_buffer *tmp_buffer = NULL;
|
||||
static struct wlr_texture *tmp_texture = NULL;
|
||||
|
||||
/* TODO: This looks way too complicated to just get the used format */
|
||||
struct wlr_drm_format wlr_drm_format = {0};
|
||||
struct wlr_shm_attributes shm_attribs = {0};
|
||||
struct wlr_dmabuf_attributes dma_attribs = {0};
|
||||
if (wlr_buffer_get_dmabuf(output_buffer, &dma_attribs)) {
|
||||
wlr_drm_format.format = dma_attribs.format;
|
||||
wlr_drm_format.len = 1;
|
||||
wlr_drm_format.modifiers = &dma_attribs.modifier;
|
||||
} else if (wlr_buffer_get_shm(output_buffer, &shm_attribs)) {
|
||||
wlr_drm_format.format = shm_attribs.format;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Failed to read buffer format");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fetch scale-adjusted cursor coordinates */
|
||||
struct server *server = output->server;
|
||||
struct theme *theme = server->theme;
|
||||
struct wlr_cursor *cursor = server->seat.cursor;
|
||||
double ox = cursor->x;
|
||||
double oy = cursor->y;
|
||||
wlr_output_layout_output_coords(server->output_layout, output->wlr_output, &ox, &oy);
|
||||
ox *= output->wlr_output->scale;
|
||||
oy *= output->wlr_output->scale;
|
||||
if (rc.mag_width == -1 || rc.mag_height == -1) {
|
||||
fullscreen = true;
|
||||
}
|
||||
if ((ox < 0 || oy < 0 || ox >= output_buffer->width || oy >= output_buffer->height)
|
||||
&& fullscreen) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mag_scale == 0.0) {
|
||||
mag_scale = rc.mag_scale;
|
||||
}
|
||||
if (mag_scale == 0.0) {
|
||||
mag_scale = 1.0;
|
||||
}
|
||||
|
||||
if (fullscreen) {
|
||||
width = output_buffer->width;
|
||||
height = output_buffer->height;
|
||||
x = 0;
|
||||
y = 0;
|
||||
} else {
|
||||
width = rc.mag_width + 1;
|
||||
height = rc.mag_height + 1;
|
||||
x = ox - (rc.mag_width / 2.0);
|
||||
y = oy - (rc.mag_height / 2.0);
|
||||
}
|
||||
double cropped_width = width;
|
||||
double cropped_height = height;
|
||||
double dst_x = 0;
|
||||
double dst_y = 0;
|
||||
|
||||
/* Ensure everything is kept within output boundaries */
|
||||
if (x < 0) {
|
||||
cropped_width += x;
|
||||
dst_x = x * -1;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
cropped_height += y;
|
||||
dst_y = y * -1;
|
||||
y = 0;
|
||||
}
|
||||
cropped_width = MIN(cropped_width, (double)output_buffer->width - x);
|
||||
cropped_height = MIN(cropped_height, (double)output_buffer->height - y);
|
||||
|
||||
/* (Re)create the temporary buffer if required */
|
||||
if (tmp_buffer && (tmp_buffer->width != width || tmp_buffer->height != height)) {
|
||||
wlr_log(WLR_DEBUG, "tmp buffer size changed, dropping");
|
||||
assert(tmp_texture);
|
||||
wlr_texture_destroy(tmp_texture);
|
||||
wlr_buffer_drop(tmp_buffer);
|
||||
tmp_buffer = NULL;
|
||||
tmp_texture = NULL;
|
||||
}
|
||||
if (!tmp_buffer) {
|
||||
tmp_buffer = wlr_allocator_create_buffer(
|
||||
server->allocator, width, height, &wlr_drm_format);
|
||||
}
|
||||
if (!tmp_buffer) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate temporary magnifier buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Paste the magnified result back into the output buffer */
|
||||
if (!tmp_texture) {
|
||||
tmp_texture = wlr_texture_from_buffer(server->renderer, tmp_buffer);
|
||||
}
|
||||
if (!tmp_texture) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate temporary texture");
|
||||
wlr_buffer_drop(tmp_buffer);
|
||||
tmp_buffer = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Extract source region into temporary buffer */
|
||||
|
||||
struct wlr_render_pass *tmp_render_pass = wlr_renderer_begin_buffer_pass(
|
||||
server->renderer, tmp_buffer, NULL);
|
||||
|
||||
wlr_buffer_lock(output_buffer);
|
||||
struct wlr_texture *output_texture = wlr_texture_from_buffer(
|
||||
server->renderer, output_buffer);
|
||||
if (!output_texture) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
struct wlr_render_texture_options opts = {
|
||||
.texture = output_texture,
|
||||
.src_box = (struct wlr_fbox) {
|
||||
x, y, cropped_width, cropped_height },
|
||||
.dst_box = (struct wlr_box) {
|
||||
dst_x, dst_y, cropped_width, cropped_height },
|
||||
.alpha = NULL,
|
||||
};
|
||||
wlr_render_pass_add_texture(tmp_render_pass, &opts);
|
||||
if (!wlr_render_pass_submit(tmp_render_pass)) {
|
||||
wlr_log(WLR_ERROR, "Failed to extract magnifier source region");
|
||||
wlr_texture_destroy(output_texture);
|
||||
goto cleanup;
|
||||
}
|
||||
wlr_texture_destroy(output_texture);
|
||||
|
||||
/* Render to the output buffer itself */
|
||||
tmp_render_pass = wlr_renderer_begin_buffer_pass(
|
||||
server->renderer, output_buffer, NULL);
|
||||
|
||||
/* Borders */
|
||||
if (fullscreen) {
|
||||
border_box.x = 0;
|
||||
border_box.y = 0;
|
||||
border_box.width = width;
|
||||
border_box.height = height;
|
||||
} else {
|
||||
border_box.x = ox - (width / 2 + theme->mag_border_width);
|
||||
border_box.y = oy - (height / 2 + theme->mag_border_width);
|
||||
border_box.width = (width + theme->mag_border_width * 2);
|
||||
border_box.height = (height + theme->mag_border_width * 2);
|
||||
struct wlr_render_rect_options bg_opts = {
|
||||
.box = border_box,
|
||||
.color = (struct wlr_render_color) {
|
||||
.r = theme->mag_border_color[0],
|
||||
.g = theme->mag_border_color[1],
|
||||
.b = theme->mag_border_color[2],
|
||||
.a = theme->mag_border_color[3]
|
||||
},
|
||||
.clip = NULL,
|
||||
};
|
||||
wlr_render_pass_add_rect(tmp_render_pass, &bg_opts);
|
||||
}
|
||||
|
||||
src_box.width = width / mag_scale;
|
||||
src_box.height = height / mag_scale;
|
||||
dst_box.width = width;
|
||||
dst_box.height = height;
|
||||
|
||||
if (fullscreen) {
|
||||
src_box.x = CLAMP(ox - (ox / mag_scale), 0.0,
|
||||
width * (mag_scale - 1.0) / mag_scale);
|
||||
src_box.y = CLAMP(oy - (oy / mag_scale), 0.0,
|
||||
height * (mag_scale - 1.0) / mag_scale);
|
||||
dst_box.x = 0;
|
||||
dst_box.y = 0;
|
||||
} else {
|
||||
src_box.x = width * (mag_scale - 1.0) / (2.0 * mag_scale);
|
||||
src_box.y = height * (mag_scale - 1.0) / (2.0 * mag_scale);
|
||||
dst_box.x = ox - (width / 2);
|
||||
dst_box.y = oy - (height / 2);
|
||||
}
|
||||
|
||||
opts = (struct wlr_render_texture_options) {
|
||||
.texture = tmp_texture,
|
||||
.src_box = src_box,
|
||||
.dst_box = dst_box,
|
||||
.alpha = NULL,
|
||||
.clip = NULL,
|
||||
.filter_mode = rc.mag_filter ? WLR_SCALE_FILTER_BILINEAR
|
||||
: WLR_SCALE_FILTER_NEAREST,
|
||||
};
|
||||
wlr_render_pass_add_texture(tmp_render_pass, &opts);
|
||||
if (!wlr_render_pass_submit(tmp_render_pass)) {
|
||||
wlr_log(WLR_ERROR, "Failed to submit render pass");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* And finally mark the extra damage */
|
||||
*damage = border_box;
|
||||
damage->width += 1;
|
||||
damage->height += 1;
|
||||
|
||||
cleanup:
|
||||
wlr_buffer_unlock(output_buffer);
|
||||
}
|
||||
|
||||
bool
|
||||
output_wants_magnification(struct output *output)
|
||||
{
|
||||
static double x = -1;
|
||||
static double y = -1;
|
||||
struct wlr_cursor *cursor = output->server->seat.cursor;
|
||||
if (!magnify_on) {
|
||||
x = -1;
|
||||
y = -1;
|
||||
return false;
|
||||
}
|
||||
if (cursor->x == x && cursor->y == y) {
|
||||
return false;
|
||||
}
|
||||
x = cursor->x;
|
||||
y = cursor->y;
|
||||
return output_nearest_to_cursor(output->server) == output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Toggles magnification on and off
|
||||
*/
|
||||
|
||||
void
|
||||
magnify_toggle(struct server *server)
|
||||
{
|
||||
struct output *output = output_nearest_to_cursor(server);
|
||||
|
||||
if (magnify_on) {
|
||||
magnify_on = false;
|
||||
} else {
|
||||
magnify_on = true;
|
||||
}
|
||||
|
||||
if (output) {
|
||||
wlr_output_schedule_frame(output->wlr_output);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Increases and decreases magnification scale
|
||||
*/
|
||||
|
||||
void
|
||||
magnify_set_scale(struct server *server, enum magnify_dir dir)
|
||||
{
|
||||
struct output *output = output_nearest_to_cursor(server);
|
||||
|
||||
if (dir == MAGNIFY_INCREASE) {
|
||||
if (magnify_on) {
|
||||
mag_scale += rc.mag_increment;
|
||||
} else {
|
||||
magnify_on = true;
|
||||
mag_scale = 1.0 + rc.mag_increment;
|
||||
}
|
||||
} else {
|
||||
if (magnify_on && mag_scale > 1.0 + rc.mag_increment) {
|
||||
mag_scale -= rc.mag_increment;
|
||||
} else {
|
||||
magnify_on = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (output) {
|
||||
wlr_output_schedule_frame(output->wlr_output);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Report whether magnification is enabled
|
||||
*/
|
||||
|
||||
bool
|
||||
is_magnify_on(void)
|
||||
{
|
||||
return magnify_on;
|
||||
}
|
||||
|
||||
|
|
@ -9,6 +9,7 @@ labwc_sources = files(
|
|||
'idle.c',
|
||||
'interactive.c',
|
||||
'layers.c',
|
||||
'magnifier.c',
|
||||
'main.c',
|
||||
'node.c',
|
||||
'osd.c',
|
||||
|
|
|
|||
11
src/theme.c
11
src/theme.c
|
|
@ -571,6 +571,10 @@ theme_builtin(struct theme *theme, struct server *server)
|
|||
memset(theme->snapping_overlay_edge.border_color, 0,
|
||||
sizeof(theme->snapping_overlay_edge.border_color));
|
||||
theme->snapping_overlay_edge.border_color[0][0] = FLT_MIN;
|
||||
|
||||
/* magnifier */
|
||||
parse_hexstr("#ff0000", theme->mag_border_color);
|
||||
theme->mag_border_width = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -826,6 +830,13 @@ entry(struct theme *theme, const char *key, const char *value)
|
|||
if (match_glob(key, "snapping.overlay.edge.border.color")) {
|
||||
parse_hexstrs(value, theme->snapping_overlay_edge.border_color);
|
||||
}
|
||||
|
||||
if (match_glob(key, "magnifier.border.width")) {
|
||||
theme->mag_border_width = atoi(value);
|
||||
}
|
||||
if (match_glob(key, "magnifier.border.color")) {
|
||||
parse_hexstr(value, theme->mag_border_color);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue