compositor: Remove desktop zoom

Zoom is a neat trick, but in its current form it's very hard to test
and maintain.

It also causes output damage to scale outside of the output's boundaries,
which leads to an extra clipping step that's only necessary when zoom
is enabled.

Remove it to simplify desktop-shell and compositor.

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
dev
Derek Foreman 3 years ago committed by Daniel Stone
parent dc3b349325
commit 66374d48f1
  1. 73
      desktop-shell/shell.c
  2. 21
      include/libweston/libweston.h
  3. 29
      libweston/backend-drm/drm.c
  4. 3
      libweston/backend.h
  5. 37
      libweston/compositor.c
  6. 1
      libweston/meson.build
  7. 2
      libweston/renderer-gl/gl-renderer.c
  8. 184
      libweston/zoom.c

@ -3421,71 +3421,6 @@ surface_opacity_binding(struct weston_pointer *pointer,
weston_surface_damage(surface); weston_surface_damage(surface);
} }
static void
do_zoom(struct weston_seat *seat, const struct timespec *time, uint32_t key,
uint32_t axis, double value)
{
struct weston_compositor *compositor = seat->compositor;
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
struct weston_output *output;
float increment;
if (!pointer) {
weston_log("Zoom hotkey pressed but seat '%s' contains no pointer.\n", seat->seat_name);
return;
}
wl_list_for_each(output, &compositor->output_list, link) {
if (pixman_region32_contains_point(&output->region,
wl_fixed_to_double(pointer->x),
wl_fixed_to_double(pointer->y),
NULL)) {
if (key == KEY_PAGEUP)
increment = output->zoom.increment;
else if (key == KEY_PAGEDOWN)
increment = -output->zoom.increment;
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
/* For every pixel zoom 20th of a step */
increment = output->zoom.increment *
-value / 20.0;
else
increment = 0;
output->zoom.level += increment;
if (output->zoom.level < 0.0)
output->zoom.level = 0.0;
else if (output->zoom.level > output->zoom.max_level)
output->zoom.level = output->zoom.max_level;
if (!output->zoom.active) {
if (output->zoom.level <= 0.0)
continue;
weston_output_activate_zoom(output, seat);
}
output->zoom.spring_z.target = output->zoom.level;
weston_output_update_zoom(output);
}
}
}
static void
zoom_axis_binding(struct weston_pointer *pointer, const struct timespec *time,
struct weston_pointer_axis_event *event,
void *data)
{
do_zoom(pointer->seat, time, 0, event->axis, event->value);
}
static void
zoom_key_binding(struct weston_keyboard *keyboard, const struct timespec *time,
uint32_t key, void *data)
{
do_zoom(keyboard->seat, time, key, 0, 0);
}
static void static void
terminate_binding(struct weston_keyboard *keyboard, const struct timespec *time, terminate_binding(struct weston_keyboard *keyboard, const struct timespec *time,
uint32_t key, void *data) uint32_t key, void *data)
@ -5022,14 +4957,6 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
MODIFIER_SUPER | MODIFIER_ALT, MODIFIER_SUPER | MODIFIER_ALT,
surface_opacity_binding, NULL); surface_opacity_binding, NULL);
weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL,
mod, zoom_axis_binding,
NULL);
weston_compositor_add_key_binding(ec, KEY_PAGEUP, mod,
zoom_key_binding, NULL);
weston_compositor_add_key_binding(ec, KEY_PAGEDOWN, mod,
zoom_key_binding, NULL);
weston_compositor_add_key_binding(ec, KEY_M, mod | MODIFIER_SHIFT, weston_compositor_add_key_binding(ec, KEY_M, mod | MODIFIER_SHIFT,
maximize_binding, NULL); maximize_binding, NULL);
weston_compositor_add_key_binding(ec, KEY_F, mod | MODIFIER_SHIFT, weston_compositor_add_key_binding(ec, KEY_F, mod | MODIFIER_SHIFT,

@ -150,21 +150,6 @@ struct weston_spring {
uint32_t clip; uint32_t clip;
}; };
struct weston_output_zoom {
bool active;
float increment;
float level;
float max_level;
float trans_x, trans_y;
struct {
double x, y;
} current;
struct weston_seat *seat;
struct weston_animation animation_z;
struct weston_spring spring_z;
struct wl_listener motion_listener;
};
/* bit compatible with drm definitions. */ /* bit compatible with drm definitions. */
enum dpms_enum { enum dpms_enum {
WESTON_DPMS_ON, WESTON_DPMS_ON,
@ -324,7 +309,6 @@ struct weston_output {
/** For cancelling the idle_repaint callback on output destruction. */ /** For cancelling the idle_repaint callback on output destruction. */
struct wl_event_source *idle_repaint_source; struct wl_event_source *idle_repaint_source;
struct weston_output_zoom zoom;
int dirty; int dirty;
struct wl_signal frame_signal; struct wl_signal frame_signal;
struct wl_signal destroy_signal; /**< sent when disabled */ struct wl_signal destroy_signal; /**< sent when disabled */
@ -1876,11 +1860,6 @@ void
weston_compositor_exit_with_code(struct weston_compositor *compositor, weston_compositor_exit_with_code(struct weston_compositor *compositor,
int exit_code); int exit_code);
void void
weston_output_update_zoom(struct weston_output *output);
void
weston_output_activate_zoom(struct weston_output *output,
struct weston_seat *seat);
void
weston_output_add_destroy_listener(struct weston_output *output, weston_output_add_destroy_listener(struct weston_output *output,
struct wl_listener *listener); struct wl_listener *listener);
struct wl_listener * struct wl_listener *

@ -414,27 +414,14 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
pixman_region32_init(&scanout_damage); pixman_region32_init(&scanout_damage);
pixman_region32_copy(&scanout_damage, damage); pixman_region32_copy(&scanout_damage, damage);
if (output->base.zoom.active) { pixman_region32_translate(&scanout_damage,
pixman_region32_t clip; -output->base.x, -output->base.y);
weston_transformed_region(output->base.width,
weston_matrix_transform_region(&scanout_damage, output->base.height,
&output->base.matrix, output->base.transform,
&scanout_damage); output->base.current_scale,
pixman_region32_init_rect(&clip, 0, 0, &scanout_damage,
output->base.width, &scanout_damage);
output->base.height);
pixman_region32_intersect(&scanout_damage, &scanout_damage, &clip);
pixman_region32_fini(&clip);
} else {
pixman_region32_translate(&scanout_damage,
-output->base.x, -output->base.y);
weston_transformed_region(output->base.width,
output->base.height,
output->base.transform,
output->base.current_scale,
&scanout_damage,
&scanout_damage);
}
assert(scanout_state->damage_blob_id == 0); assert(scanout_state->damage_blob_id == 0);

@ -154,9 +154,6 @@ weston_output_damage(struct weston_output *output);
void void
weston_output_release(struct weston_output *output); weston_output_release(struct weston_output *output);
void
weston_output_init_zoom(struct weston_output *output);
void void
weston_output_finish_frame(struct weston_output *output, weston_output_finish_frame(struct weston_output *output,
const struct timespec *stamp, const struct timespec *stamp,

@ -6064,11 +6064,8 @@ weston_compositor_reflow_outputs(struct weston_compositor *compositor,
* \param region The region to be transformed in-place. * \param region The region to be transformed in-place.
* *
* This takes a region in the global coordinate system, and takes into account * This takes a region in the global coordinate system, and takes into account
* output position, transform and scale, and the zoom, and converts the region * output position, transform and scale, and converts the region into output
* into output pixel coordinates in the framebuffer. * pixel coordinates in the framebuffer.
*
* Uses floating-point operations if zoom is active, which may round to expand
* the region.
* *
* \internal * \internal
* \ingroup output * \ingroup output
@ -6077,34 +6074,19 @@ WL_EXPORT void
weston_output_region_from_global(struct weston_output *output, weston_output_region_from_global(struct weston_output *output,
pixman_region32_t *region) pixman_region32_t *region)
{ {
if (output->zoom.active) { pixman_region32_translate(region, -output->x, -output->y);
weston_matrix_transform_region(region, &output->matrix, region); weston_transformed_region(output->width, output->height,
} else { output->transform,
pixman_region32_translate(region, -output->x, -output->y); output->current_scale,
weston_transformed_region(output->width, output->height, region, region);
output->transform,
output->current_scale,
region, region);
}
} }
static void static void
weston_output_update_matrix(struct weston_output *output) weston_output_update_matrix(struct weston_output *output)
{ {
float magnification;
weston_matrix_init(&output->matrix); weston_matrix_init(&output->matrix);
weston_matrix_translate(&output->matrix, -output->x, -output->y, 0); weston_matrix_translate(&output->matrix, -output->x, -output->y, 0);
if (output->zoom.active) {
magnification = 1 / (1 - output->zoom.spring_z.current);
weston_output_update_zoom(output);
weston_matrix_translate(&output->matrix, -output->zoom.trans_x,
-output->zoom.trans_y, 0);
weston_matrix_scale(&output->matrix, magnification,
magnification, 1.0);
}
switch (output->transform) { switch (output->transform) {
case WL_OUTPUT_TRANSFORM_FLIPPED: case WL_OUTPUT_TRANSFORM_FLIPPED:
case WL_OUTPUT_TRANSFORM_FLIPPED_90: case WL_OUTPUT_TRANSFORM_FLIPPED_90:
@ -6682,8 +6664,8 @@ weston_output_create_heads_string(struct weston_output *output)
* Output coordinates are calculated and each new output is by default * Output coordinates are calculated and each new output is by default
* assigned to the right of previous one. * assigned to the right of previous one.
* *
* Sets up the transformation, zoom, and geometry of the output using * Sets up the transformation, and geometry of the output using the
* the properties that need to be configured by the compositor. * properties that need to be configured by the compositor.
* *
* Establishes a repaint timer for the output with the relevant display * Establishes a repaint timer for the output with the relevant display
* object's event loop. See output_repaint_timer_handler(). * object's event loop. See output_repaint_timer_handler().
@ -6762,7 +6744,6 @@ weston_output_enable(struct weston_output *output)
wl_signal_init(&output->destroy_signal); wl_signal_init(&output->destroy_signal);
weston_output_transform_scale_init(output, output->transform, output->scale); weston_output_transform_scale_init(output, output->transform, output->scale);
weston_output_init_zoom(output);
weston_output_init_geometry(output, x, y); weston_output_init_geometry(output, x, y);
weston_output_damage(output); weston_output_damage(output);

@ -35,7 +35,6 @@ srcs_libweston = [
'weston-log-flight-rec.c', 'weston-log-flight-rec.c',
'weston-log.c', 'weston-log.c',
'weston-direct-display.c', 'weston-direct-display.c',
'zoom.c',
linux_dmabuf_unstable_v1_protocol_c, linux_dmabuf_unstable_v1_protocol_c,
linux_dmabuf_unstable_v1_server_protocol_h, linux_dmabuf_unstable_v1_server_protocol_h,
linux_explicit_synchronization_unstable_v1_protocol_c, linux_explicit_synchronization_unstable_v1_protocol_c,

@ -1068,7 +1068,7 @@ draw_paint_node(struct weston_paint_node *pnode,
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
if (pnode->view->transform.enabled || pnode->output->zoom.active || if (pnode->view->transform.enabled ||
pnode->output->current_scale != pnode->surface->buffer_viewport.buffer.scale) pnode->output->current_scale != pnode->surface->buffer_viewport.buffer.scale)
filter = GL_LINEAR; filter = GL_LINEAR;
else else

@ -1,184 +0,0 @@
/*
* Copyright © 2012 Scott Moreau
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "config.h"
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <libweston/libweston.h>
#include "backend.h"
#include "libweston-internal.h"
#include "text-cursor-position-server-protocol.h"
#include "shared/helpers.h"
static void
weston_zoom_frame_z(struct weston_animation *animation,
struct weston_output *output,
const struct timespec *time)
{
if (animation->frame_counter <= 1)
output->zoom.spring_z.timestamp = *time;
weston_spring_update(&output->zoom.spring_z, time);
if (output->zoom.spring_z.current > output->zoom.max_level)
output->zoom.spring_z.current = output->zoom.max_level;
else if (output->zoom.spring_z.current < 0.0)
output->zoom.spring_z.current = 0.0;
if (weston_spring_done(&output->zoom.spring_z)) {
if (output->zoom.active && output->zoom.level <= 0.0) {
output->zoom.active = false;
output->zoom.seat = NULL;
weston_output_disable_planes_decr(output);
wl_list_remove(&output->zoom.motion_listener.link);
}
output->zoom.spring_z.current = output->zoom.level;
wl_list_remove(&animation->link);
wl_list_init(&animation->link);
}
output->dirty = 1;
weston_output_damage(output);
}
static void
zoom_area_center_from_point(struct weston_output *output,
double *x, double *y)
{
float level = output->zoom.spring_z.current;
*x = (*x - output->x) * level + output->width / 2.;
*y = (*y - output->y) * level + output->height / 2.;
}
static void
weston_output_update_zoom_transform(struct weston_output *output)
{
double x = output->zoom.current.x; /* global pointer coords */
double y = output->zoom.current.y;
float level;
level = output->zoom.spring_z.current;
if (!output->zoom.active || level > output->zoom.max_level ||
level == 0.0f)
return;
zoom_area_center_from_point(output, &x, &y);
output->zoom.trans_x = x - output->width / 2;
output->zoom.trans_y = y - output->height / 2;
if (output->zoom.trans_x < 0)
output->zoom.trans_x = 0;
if (output->zoom.trans_y < 0)
output->zoom.trans_y = 0;
if (output->zoom.trans_x > level * output->width)
output->zoom.trans_x = level * output->width;
if (output->zoom.trans_y > level * output->height)
output->zoom.trans_y = level * output->height;
}
static void
weston_zoom_transition(struct weston_output *output)
{
if (output->zoom.level != output->zoom.spring_z.current) {
output->zoom.spring_z.target = output->zoom.level;
if (wl_list_empty(&output->zoom.animation_z.link)) {
output->zoom.animation_z.frame_counter = 0;
wl_list_insert(output->animation_list.prev,
&output->zoom.animation_z.link);
}
}
output->dirty = 1;
weston_output_damage(output);
}
WL_EXPORT void
weston_output_update_zoom(struct weston_output *output)
{
struct weston_seat *seat = output->zoom.seat;
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
if (!pointer)
return;
assert(output->zoom.active);
output->zoom.current.x = wl_fixed_to_double(pointer->x);
output->zoom.current.y = wl_fixed_to_double(pointer->y);
weston_zoom_transition(output);
weston_output_update_zoom_transform(output);
}
static void
motion(struct wl_listener *listener, void *data)
{
struct weston_output_zoom *zoom =
container_of(listener, struct weston_output_zoom, motion_listener);
struct weston_output *output =
container_of(zoom, struct weston_output, zoom);
weston_output_update_zoom(output);
}
WL_EXPORT void
weston_output_activate_zoom(struct weston_output *output,
struct weston_seat *seat)
{
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
if (!pointer || output->zoom.active)
return;
output->zoom.active = true;
output->zoom.seat = seat;
weston_output_disable_planes_incr(output);
wl_signal_add(&pointer->motion_signal,
&output->zoom.motion_listener);
}
WL_EXPORT void
weston_output_init_zoom(struct weston_output *output)
{
output->zoom.active = false;
output->zoom.seat = NULL;
output->zoom.increment = 0.07;
output->zoom.max_level = 0.95;
output->zoom.level = 0.0;
output->zoom.trans_x = 0.0;
output->zoom.trans_y = 0.0;
weston_spring_init(&output->zoom.spring_z, 250.0, 0.0, 0.0);
output->zoom.spring_z.friction = 1000;
output->zoom.animation_z.frame = weston_zoom_frame_z;
wl_list_init(&output->zoom.animation_z.link);
output->zoom.motion_listener.notify = motion;
}
Loading…
Cancel
Save