mirror of
https://github.com/labwc/labwc.git
synced 2026-02-28 01:40:29 -05:00
Add resistance when dragging tiled windows
Adds a config option <snapping><dragResistance> with default value 20. This prevents tiled/maximized windows from being unintentionally untiled.
This commit is contained in:
parent
750d37b16c
commit
c202d77c2d
8 changed files with 82 additions and 4 deletions
|
|
@ -347,6 +347,10 @@ extending outward from the snapped edge.
|
||||||
SnapToEdge action for that edge. A *range* of 0 disables snapping via
|
SnapToEdge action for that edge. A *range* of 0 disables snapping via
|
||||||
interactive moves. Default is 1.
|
interactive moves. Default is 1.
|
||||||
|
|
||||||
|
*<snapping><dragResistance>*
|
||||||
|
Sets the movement of cursor in pixel required for a tiled or maximized
|
||||||
|
window to be moved with an interactive move. Default is 20.
|
||||||
|
|
||||||
*<snapping><overlay><enabled>* [yes|no]
|
*<snapping><overlay><enabled>* [yes|no]
|
||||||
Show an overlay when snapping to a window to an edge. Default is yes.
|
Show an overlay when snapping to a window to an edge. Default is yes.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@
|
||||||
<snapping>
|
<snapping>
|
||||||
<!-- Set range to 0 to disable window snapping completely -->
|
<!-- Set range to 0 to disable window snapping completely -->
|
||||||
<range>1</range>
|
<range>1</range>
|
||||||
|
<dragResistance>20</dragResistance>
|
||||||
<overlay enabled="yes">
|
<overlay enabled="yes">
|
||||||
<delay inner="500" outer="500" />
|
<delay inner="500" outer="500" />
|
||||||
</overlay>
|
</overlay>
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ struct rcxml {
|
||||||
int snap_overlay_delay_outer;
|
int snap_overlay_delay_outer;
|
||||||
bool snap_top_maximize;
|
bool snap_top_maximize;
|
||||||
enum tiling_events_mode snap_tiling_events_mode;
|
enum tiling_events_mode snap_tiling_events_mode;
|
||||||
|
int snap_drag_resistance;
|
||||||
|
|
||||||
enum resize_indicator_mode resize_indicator;
|
enum resize_indicator_mode resize_indicator;
|
||||||
bool resize_draw_contents;
|
bool resize_draw_contents;
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,16 @@ struct server {
|
||||||
/* cursor interactive */
|
/* cursor interactive */
|
||||||
enum input_mode input_mode;
|
enum input_mode input_mode;
|
||||||
struct view *grabbed_view;
|
struct view *grabbed_view;
|
||||||
|
/*
|
||||||
|
* When an interactive move is requested for tiled/maximized views by CSD
|
||||||
|
* clients or by Drag actions, the actual motion and untiling of the view
|
||||||
|
* can be delayed to prevent the view from being unintentionally untiled.
|
||||||
|
* During this delay, move_pending is set.
|
||||||
|
*/
|
||||||
|
bool move_pending;
|
||||||
|
/* Cursor position when interactive move/resize is requested */
|
||||||
double grab_x, grab_y;
|
double grab_x, grab_y;
|
||||||
|
/* View geometry when interactive move/resize is requested */
|
||||||
struct wlr_box grab_box;
|
struct wlr_box grab_box;
|
||||||
uint32_t resize_edges;
|
uint32_t resize_edges;
|
||||||
|
|
||||||
|
|
@ -497,6 +506,15 @@ void seat_output_layout_changed(struct seat *seat);
|
||||||
*/
|
*/
|
||||||
void interactive_anchor_to_cursor(struct view *view, struct wlr_box *geometry);
|
void interactive_anchor_to_cursor(struct view *view, struct wlr_box *geometry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* interactive_move_tiled_view_to() - Un-tile the tiled/maximized view at the
|
||||||
|
* start of an interactive move or when an interactive move is pending.
|
||||||
|
* Returns true if the distance of cursor motion exceeds the value of
|
||||||
|
* <snapping><dragResistance> and the view is un-tiled.
|
||||||
|
*/
|
||||||
|
bool interactive_move_tiled_view_to(struct server *server, struct view *view,
|
||||||
|
struct wlr_box *geometry);
|
||||||
|
|
||||||
void interactive_begin(struct view *view, enum input_mode mode, uint32_t edges);
|
void interactive_begin(struct view *view, enum input_mode mode, uint32_t edges);
|
||||||
void interactive_finish(struct view *view);
|
void interactive_finish(struct view *view);
|
||||||
void interactive_cancel(struct view *view);
|
void interactive_cancel(struct view *view);
|
||||||
|
|
|
||||||
|
|
@ -971,6 +971,8 @@ entry(xmlNode *node, char *nodename, char *content)
|
||||||
} else {
|
} else {
|
||||||
wlr_log(WLR_ERROR, "ignoring invalid value for notifyClient");
|
wlr_log(WLR_ERROR, "ignoring invalid value for notifyClient");
|
||||||
}
|
}
|
||||||
|
} else if (!strcasecmp(nodename, "dragResistance.snapping")) {
|
||||||
|
rc.snap_drag_resistance = atoi(content);
|
||||||
|
|
||||||
/* <windowSwitcher show="" preview="" outlines="" /> */
|
/* <windowSwitcher show="" preview="" outlines="" /> */
|
||||||
} else if (!strcasecmp(nodename, "show.windowSwitcher")) {
|
} else if (!strcasecmp(nodename, "show.windowSwitcher")) {
|
||||||
|
|
@ -1278,6 +1280,7 @@ rcxml_init(void)
|
||||||
rc.snap_overlay_delay_outer = 500;
|
rc.snap_overlay_delay_outer = 500;
|
||||||
rc.snap_top_maximize = true;
|
rc.snap_top_maximize = true;
|
||||||
rc.snap_tiling_events_mode = LAB_TILING_EVENTS_ALWAYS;
|
rc.snap_tiling_events_mode = LAB_TILING_EVENTS_ALWAYS;
|
||||||
|
rc.snap_drag_resistance = 20;
|
||||||
|
|
||||||
rc.window_switcher.show = true;
|
rc.window_switcher.show = true;
|
||||||
rc.window_switcher.preview = true;
|
rc.window_switcher.preview = true;
|
||||||
|
|
|
||||||
|
|
@ -232,9 +232,19 @@ request_set_primary_selection_notify(struct wl_listener *listener, void *data)
|
||||||
static void
|
static void
|
||||||
process_cursor_move(struct server *server, uint32_t time)
|
process_cursor_move(struct server *server, uint32_t time)
|
||||||
{
|
{
|
||||||
|
struct view *view = server->grabbed_view;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Un-tile the view when interactive move is delayed and the distance
|
||||||
|
* of cursor movement exceeds <snapping><dragResistance>.
|
||||||
|
*/
|
||||||
|
if (server->move_pending && !interactive_move_tiled_view_to(
|
||||||
|
server, server->grabbed_view, &server->grab_box)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
double dx = server->seat.cursor->x - server->grab_x;
|
double dx = server->seat.cursor->x - server->grab_x;
|
||||||
double dy = server->seat.cursor->y - server->grab_y;
|
double dy = server->seat.cursor->y - server->grab_y;
|
||||||
struct view *view = server->grabbed_view;
|
|
||||||
|
|
||||||
/* Move the grabbed view to the new position. */
|
/* Move the grabbed view to the new position. */
|
||||||
dx += server->grab_box.x;
|
dx += server->grab_box.x;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
#include <assert.h>
|
||||||
#include "edges.h"
|
#include "edges.h"
|
||||||
#include "input/keyboard.h"
|
#include "input/keyboard.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
|
@ -31,6 +32,38 @@ interactive_anchor_to_cursor(struct view *view, struct wlr_box *geometry)
|
||||||
view->current.height, geometry->height);
|
view->current.height, geometry->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
interactive_move_tiled_view_to(struct server *server, struct view *view,
|
||||||
|
struct wlr_box *geometry)
|
||||||
|
{
|
||||||
|
assert(!view_is_floating(view));
|
||||||
|
|
||||||
|
int resistance = rc.snap_drag_resistance;
|
||||||
|
|
||||||
|
if (server->input_mode == LAB_INPUT_STATE_MOVE) {
|
||||||
|
/* When called from cursor motion handler */
|
||||||
|
assert(server->move_pending && server->grabbed_view == view);
|
||||||
|
|
||||||
|
double dx = server->seat.cursor->x - server->grab_x;
|
||||||
|
double dy = server->seat.cursor->y - server->grab_y;
|
||||||
|
if (dx * dx + dy * dy < resistance * resistance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* When called from interactive_begin() */
|
||||||
|
if (resistance > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
view_set_shade(view, false);
|
||||||
|
view_set_untiled(view);
|
||||||
|
view_restore_to(view, *geometry);
|
||||||
|
server->move_pending = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
|
interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
|
||||||
{
|
{
|
||||||
|
|
@ -83,9 +116,15 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
|
||||||
interactive_anchor_to_cursor(view, &geometry);
|
interactive_anchor_to_cursor(view, &geometry);
|
||||||
}
|
}
|
||||||
|
|
||||||
view_set_shade(view, false);
|
/*
|
||||||
view_set_untiled(view);
|
* If <snapping><dragResistance> is non-zero, the
|
||||||
view_restore_to(view, geometry);
|
* tiled/maximized view is un-tiled later in cursor
|
||||||
|
* motion handler.
|
||||||
|
*/
|
||||||
|
if (!interactive_move_tiled_view_to(
|
||||||
|
server, view, &geometry)) {
|
||||||
|
server->move_pending = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Store natural geometry at start of move */
|
/* Store natural geometry at start of move */
|
||||||
view_store_natural_geometry(view);
|
view_store_natural_geometry(view);
|
||||||
|
|
@ -261,6 +300,7 @@ interactive_cancel(struct view *view)
|
||||||
|
|
||||||
view->server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
|
view->server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
|
||||||
view->server->grabbed_view = NULL;
|
view->server->grabbed_view = NULL;
|
||||||
|
view->server->move_pending = false;
|
||||||
|
|
||||||
/* Update focus/cursor image */
|
/* Update focus/cursor image */
|
||||||
cursor_update_focus(view->server);
|
cursor_update_focus(view->server);
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@ do_late_positioning(struct view *view)
|
||||||
if (server->input_mode == LAB_INPUT_STATE_MOVE
|
if (server->input_mode == LAB_INPUT_STATE_MOVE
|
||||||
&& view == server->grabbed_view) {
|
&& view == server->grabbed_view) {
|
||||||
/* Keep view underneath cursor */
|
/* Keep view underneath cursor */
|
||||||
|
/* TODO: resistance is not considered */
|
||||||
interactive_anchor_to_cursor(view, &view->pending);
|
interactive_anchor_to_cursor(view, &view->pending);
|
||||||
/* Update grab offsets */
|
/* Update grab offsets */
|
||||||
server->grab_x = server->seat.cursor->x;
|
server->grab_x = server->seat.cursor->x;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue