Commit graph

56 commits

Author SHA1 Message Date
Andrew J. Hesford
b34f2c9d85 Revert "src/interactive.c: don't unshade when view is un-tiled by dragging"
When labwc un-tiles views, it generally changes their size, which sends
a configure request to the client. However, because the view has been
disabled in the wlroots scene, it will not receive and process the
configure when labwc expects. Instead, the handling will be deferred
until the user unshades the view at some arbitrary time in the future,
resulting in labwc registering complains like

    [../src/xdg.c:239] client did not respond to configure request in 100 ms

Furthermore, the reconfigure will still generally produce flicker (as
the view opens in its tiled size and then jumps to its natural
geometry). Because skipping the unshade might cause client problems and
doesn't eliminate the problem it sought to resolve, let's revert this.

This reverts commit 2e19bd4d5b.
2024-08-28 08:24:26 -04:00
tokyo4j
1f1bdad087 interactive: allow moving horizontally/vertically maximized window
Applies drag resistance unidirectionally for horizontally/vertically
maximized windows, allowing them to be dragged without being untiled
immediately. When the distance of cursor movement orthogonal to the
maximized direction exceeds <resistance><unMaximizeThreshold>.

While dragging a horizontally/vertically maximized window, edge/region
snapping is disabled to prevent unintentional snapping and overlays.

This commit also includes some refactoring to simplify the logic.
2024-08-26 20:30:22 +02:00
tokyo4j
2e19bd4d5b src/interactive.c: don't unshade when view is un-tiled by dragging
Unshading a maximized/tiled window at the start of interactive move
doesn't seem to be useful and caused flicker.
2024-08-26 20:30:22 +02:00
tokyo4j
670cc0f511 Rename <snapping><dragResistance> to <resistance><unSnapThreshold>
As we already have <resistance><{screen,window}EdgeStrength>,
<resistance> will be a better place for this setting.
2024-08-08 09:49:53 +09:00
John Lindgren
1a339f9c7e xdg: account for drag resistance in do_late_positioning()
The position where the view should be anchored can now be slightly
different from the current cursor position.

Addresses a TODO from #2009.
2024-08-06 13:51:35 +09:00
tokyo4j
c202d77c2d 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.
2024-08-02 23:40:26 +02:00
John Lindgren
3be8fe25f3 xdg: handle initially maximized xdg-shell views better
Currently, initially maximized (or fullscreen) xdg-shell views exhibit
one of two issues:

 - some (e.g. GTK and Qt apps) paint an initial frame un-maximized
   (before the "map" event) and only maximize in a later commit

 - others (e.g. foot) maximize immediately without flicker, but never
   store a valid natural size, so we end up using a fallback (640x480)

Under KWin, neither of these issues occur, so I looked into what labwc
is doing wrong. It seems that:

 - wlroots internally sends an initial configure event with a size of
   0x0 to all xdg-shell views. This requests the client to set its own
   preferred (a.k.a. natural) size.

 - For an initially maximized/fullscreen view, the initial configure
   event should contain the maximized/fullscreen size rather than 0x0.
   In labwc, this means we have to call wlr_xdg_toplevel_set_size()
   earlier, i.e. from the new_surface event. Tracing with WAYLAND_DEBUG
   shows that the initial configure event now has the correct geometry,
   matching KWin behavior. With this change, GTK and Qt apps no longer
   paint an incorrect un-maximized frame.

 - However, this means that all xdg-shell views now suffer from the same
   issue as foot, where we never receive a commit with the un-maximized
   (natural) geometry. The correct way to get the natural geometry seems
   to be to wait until we want to un-maximize, and send a configure
   event of 0x0 at that point.

Sending a configure event of 0x0 when un-maximizing is a bit annoying as
it breaks some assumptions in labwc code. In particular:

 - view->natural_geometry may now be unknown (0x0), requiring various
   wlr_box_empty() checks sprinkled around. I added these in all the
   obvious places, but there could be some code paths that I missed.

 - Positioning the newly un-maximized view within view_maximize() no
   longer works since we don't know the natural size. Instead we have to
   run the positioning logic from the surface commit handler. This
   results in some extra complexity, especially for interactive move.
   See the new do_late_positioning() function in xdg.c.

Some TODOs/FIXMEs (non-blocking in my opinion):

 - The view_wants_decorations() check is now duplicated in both the
   new_surface and map event handlers. I'm not sure if this is necessary
   but it seemed like the safest approach for now. More testing would be
   nice, particularly with various combinations of config and client SSD
   preferences.

 - Aside from the interactive move case, the "late positioning" logic
   always centers the view when un-maximizing, and does not invoke any
   of the smart placement logic. If we want to invoke smart placement
   here, I'd appreciate someone with more knowledge of that code to take
   a look and figure out how to do that correctly.
2024-07-19 22:48:39 +01:00
tokyo4j
23b96ad2a6 Replace _ with - in source file names 2024-05-22 07:10:51 +01:00
Andrew J. Hesford
2bf285a2c6 snap: cache and ignore last-snapped edge when growing or shrinking
When growing or shrinking a view by snapping to an edge, a client may
ignore the requested size and instead keep its original size or
substitute a different (possibly constrained) size. In this case, the
view may not actually contact the snapped edge, and a subsequent snap
attempt will just keep re-trying (and failing) to contact the same ege.

To mitigate this, remember the last-snapped view, snapping direction and
offset of the snapping edge in snap.c; when re-attempting a snap for the
same view in the same direction, ignore the edge that was last "hit", to
allow snapping to progress beyond the problematic edge.
2024-04-10 23:30:28 +01:00
Hiroaki Yamamoto
5cc0757390
overlay: add snap-to-edge overlay (PR #1652)
...and unify region overlay and snap-to-edge overlay into overlay.c.

Snap-to-edge overlay is delayed for 500ms to prevent flickering when
the view is dragged from an output to another (demo in discussion labwc#1613).

This also fixes a bug that region overlay is not shown when a modifier
key is re-pressed.
2024-04-05 04:35:31 +02:00
Hiroaki Yamamoto
be37f9a564
Fix various typos across the codebase 2024-03-08 13:59:20 +01:00
Consolatis
29a26d5ff7 edges: do not apply resistance to invisible edges 2024-02-14 21:20:45 +00:00
Andrew J. Hesford
9f51384b6a interactive: reset tiled state when dragging out of snapped position
This ensures that client-side decorations (and maybe other client
behaviors) behave intuitively during interative moves, but means that

    drag to snapped position -> drag to maximize -> un-maximize

will put the window back to its natural geometry (saved before the first
snap) rather than back to the snapped position. This is a change in
behavior, but a) simplifies the logic a bit, because the tiled state is
always in sync with the window geometry and b) in some sense is "more
correct", because the window has been "visually" un-tiled the minute the
window starts dragging.

Note that maximizing using an action (including the button) a window
that has been snapped and then un-maximizing the window will put the
window back to the snapped position, as it always has.
2024-01-30 07:30:07 -05:00
Andrew J. Hesford
49dc55d4f0 interactive: unify interactive_{cancel,finish} where possible
This also fixes a bug wherein dragging a window and pressing a hot-key
to maximize or fullscreen a window could leave a snap-region highlight
visible after the interactive move was canceled.
2024-01-23 10:11:52 -05:00
Consolatis
e05bedb140 feat: add Shade/Unshade/ToggleShade actions
This builds on the work of @Consolatis in #1018.

Co-authored-by: Consolatis <35009135+Consolatis@users.noreply.github.com>
Co-authored-by: Andrew J. Hesford <ajh@sideband.org>
2024-01-15 21:37:36 +00:00
Andrew J. Hesford
c229f6edc0 view: try to honor original geometry with layout changes
Whenever the output layout changes, each view's original geometry will
be captured as last_layout_geometry (if it has not already been captured
by a previous layout change), which will remain valid unless the user
modifies the view's geometry (i.e., by tiling, maximizing, moving,
resizing or full-screening). On subsequent output layout changes, views
with valid last_layout_geometry will be back to their original position
if possible, or else to the closest possible output.
2024-01-06 19:04:11 +00:00
John Lindgren
83e67b32b6 xwayland: treat X11 panel views as if fixedPosition rule is set 2023-11-29 06:48:31 +00:00
Johan Malm
368ede7460 window-rules: add fixedPosition property
...to address regression introduced by 57075ce and enables panel/desktop
clients which rely on window rules to remain in the same position when
the usable-area changes (normally because an exclusive layer-shell
clients is started/finished).

Also disallows interactive move/resize, for example by alt +
mouse-press.

Fixes: #1235
2023-11-10 21:46:15 +01:00
tokyo4j
9a8a2905ad interactive: Make window snapping with mouse more intuitive
1. Prevent window snapping triggered by mouse from moving the window
 into the adjacent output.
2. Make the coordinates used to check whether window snapping is
 triggered relative to the output the cursor is at, not the output the
 view is belonging to. This allows users to grab a tiled window and move
 it into another output or tile it again in another output in a single
 drag.
2023-11-10 19:41:36 +00:00
Consolatis
b359b1560c Move keyboard functions into input/keyboard.h 2023-10-30 21:14:04 +00:00
John Lindgren
0430f6f818 view: implement separate horizontal/vertical maximize
This is a useful (if lesser-known) feature of at least a few popular X11
window managers, for example Openbox and XFWM4. Typically right-click on
the maximize button toggles horizontal maximize, while middle-click
toggles vertical maximize.

Support in labwc uses the same configuration syntax as Openbox, where the
Maximize/ToggleMaximize actions have an optional "direction" argument:
horizontal, vertical, or both (default). The default mouse bindings match
the XFWM4 defaults (not sure what Openbox has by default).

Most of the external protocols still assume "maximized" is a Boolean,
which is no longer true internally. For the sake of the outside world,
a view is only "maximized" if maximized in both directions.

Internally, I've taken the following approach:

- SSD code decorates the view as "maximized" (i.e. hiding borders) only
  if maximized in both directions.

- Layout code (interactive move/resize, tiling, etc.) generally treats
  the view as "maximized" (with the restrictions that entails) if
  maximized in either direction. For example, moving a vertically-
  maximized view first restores the natural geometry (this differs from
  Openbox, which instead allows the view to move only horizontally.)

v2: use enum view_axis for view->maximized
v3:
  - update docs
  - allow resizing if partly maximized
  - add TODOs & corrections noted by Consolatis
2023-10-28 22:46:49 +02:00
Consolatis
58b33fb0c9 Add window resize indicator 2023-08-19 18:37:16 +02:00
Consolatis
1ee8715d57 actions: use enum for _ToEdge actions
This also improves the config robustness as invalid edge names will now
prevent the action to be created in the first place and the user gets
notified about the issue.
2023-08-02 17:57:04 +01:00
Consolatis
5aa5c12371 Prevent rare crash due to layering move / resize / menu operations
Fixes #817

Reported-by: @kode54
2023-03-07 22:23:46 +00:00
Consolatis
a4fb5b093b Prevent cursor based region-snapping when starting a move with A-Left
When wanting to snap to a region when starting the move
operation with A-Left (or a similar mousebind which includes a
modifier), the modifier - or another one - must be pressed again.

Fixes #761
2023-03-07 20:55:35 +00:00
John Lindgren
b75dbd5b38 view: Use wlr_box for current/pending geometry 2023-02-09 10:44:15 -05:00
Consolatis
07ee56176d SnapToRegion: Allow for live config updates 2023-01-11 18:52:24 +01:00
Consolatis
eb5c8cfdad SnapToRegion: Add dynamic overlay
Either uses a half transparent single rect if running
hardware accelerated or uses a solid struct multirect
outline if not.
2023-01-11 18:52:24 +01:00
Consolatis
25cea94a32 SnapToRegion: Snap when ending a move while pressing a modifier 2023-01-11 18:52:24 +01:00
Consolatis
7e99d8ba08 SnapToRegion: Add overlay while moving and pressing a modifier 2023-01-11 18:52:24 +01:00
John Lindgren
e79c95489a view: Add view_set_untiled() 2022-11-22 09:17:33 +01:00
John Lindgren
f08e931a29 include: Break out view.h from labwc.h
IMHO it encourages better design (by making dependencies more obvious)
to have source file/header file pairs like view.c/view.h, rather than a
monolithic header like labwc.h with everything in it.

I don't think we need to break up all of labwc.h at once, but maybe we
can start pulling it apart bit by bit as it's convenient.

Also:

- Move "struct border" to ssd.h so that view.h can use it without pulling
  in all of labwc.h.
- Add a missing required #include within scaled_font_buffer.h (forward
  declaration of "struct font" is not enough).
2022-11-21 21:42:37 +00:00
John Lindgren
9021020f6e interactive: Refactor natural_geometry/tiled state handling
Currently, snapping to a screen edge and then snapping to maximize
results in both the natural_geometry and tiled state of the view
getting messed up. After unmaximize, the view ends up in a weird
state (tiled location but natural/untiled size).

There are also a couple of sketchy things going on in the code:

- interactive_begin() pokes its own values into view->natural_geometry
  to force view_maximize() to set a particular geometry.

- interactive_end() "fixes" view->natural_geometry after calling
  view_maximize() to save the original geometry from the start of the
  interactive move/resize.

To fix all this:

- Adjust/expand the API of view.c so that the interactive.c can
  avoid this "back door" of overwriting view->natural_geometry
  directly.

- Save the natural geometry and the tiled state of the view in
  interactive_begin() when starting to move the view.  When done,
  interactive_end() will update the tiled state if appropriate but
  *not* overwrite the natural geometry.
2022-11-20 20:45:50 +00:00
Johan Malm
d424514e24 Fix minor coding-style violations
...based on https://github.com/johanmalm/checkpatch.pl
2022-09-22 22:39:44 +01:00
Consolatis
e30fce6c34 cursor: Use enum for server set cursor names
This mainly prevents having to use strcmp() on every mouse move.
2022-09-16 21:30:40 +01:00
John Lindgren
6c6e406507 cursor: Factor out cursor_update_common() and fix some glitches
Fix a couple of glitches seen when exiting interactive move/resize:

 - Cursor briefly set to left_ptr rather than the correct cursor image
 - Cursor not updated if the view being moved/resized is destroyed

Also make sure to exit interactive mode if the view is going fullscreen
(labwc gets very confused otherwise).

Code changes in detail:

 - Factor out set_server_cursor() which will set the correct cursor
   image for non-client areas (either XCURSOR_DEFAULT or one of the
   resize cursors).
 - Unify the logic from cursor_rebase() and process_cursor_motion by
   factoring out cursor_update_common().  This corrects some logic
   discrepancies between the two, which should be a good thing(TM).
 - Remove the extra cursor_set(XCURSOR_DEFAULT) from interactive_end()
   and instead rely on cursor_update_focus() to do the right thing.
 - Simplify cursor_button() by just calling interactive_end() when we
   want to exit interactive mode.
 - Call cursor_update_focus() from view_destroy() if the view had mouse
   focus or was being interactively moved/resized.

v2: Eliminate force_reenter parameters and figure out automatically
    when we need to re-enter the surface.
v3: Rename wlseat -> wlr_seat.
v4: Simplify client/server cursor logic.
2022-09-13 13:29:36 -04:00
Consolatis
7af74c88a8 cursor: Prevent resetting cursor icon during Move or Resize
Reported-by: @Flrian
2022-09-11 13:24:27 +01:00
John Lindgren
d5e2728c7f interactive: Don't write to view->x/y/w/h directly
Otherwise, the scene-graph isn't updated when calling
view->impl->configure(), and the view ends up in a weird
half-maximized state.
2022-09-08 20:08:03 -04:00
Consolatis
3c345201cd Restore original geometry when moving a tiled window
Fixes #391
2022-07-02 16:21:32 +01:00
Consolatis
5585977f72 Rename unmaximized_geometry to natural_geometry 2022-07-02 16:21:32 +01:00
Consolatis
3a4b55886d src/view.c: Convert SnapToEdge to use view_apply_xxx_geometry framework 2022-07-02 12:43:23 +01:00
Johan Malm
5b34c81768 Fix trivial coding style breaches 2022-04-04 20:53:36 +01:00
Consolatis
87f4a60e38 Allow mouse movements to trigger SnapToEdge 2022-01-08 10:30:03 +00:00
Consolatis
ae43d4b9d1 Unmaximize on Move 2022-01-07 22:06:21 +00:00
Johan Malm
3194d2c438 interactive: use "grab" cursor when moving
This is consistent with sway and looks better.

Relates to issue #124
2021-12-29 14:28:36 +00:00
Johan Malm
c5658fde8e interactive.c: fix style 2021-12-03 23:15:28 +00:00
Joshua Ashton
3e973c92ab interactive: Fix crash if a window is destroyed while moving it
Need to clean this up if it's our grabbed window!

Signed-off-by: Joshua Ashton <joshua@froggi.es>
2021-12-03 18:11:31 +00:00
Johan Malm
1c831bc051 interactive.c: set move/resize cursor
Fixes issue #124
2021-11-28 21:47:24 +00:00
Johan Malm
ebb632419b *.c: add SPDX-License-Identifier 2021-09-24 21:45:48 +01:00
Johan Malm
6ece805e88 interactive.c: do not allow move/resize when maximized 2021-03-06 18:34:52 +00:00