Commit graph

135 commits

Author SHA1 Message Date
John Lindgren
976136299d output: Add output_nearest_to()
Reimplement output_from_cursor_coords() as output_nearest_to_cursor().
2023-02-21 08:46:22 +01:00
John Lindgren
84294c9cfb xdg: Use wlr_xdg_surface_get_geometry() to get size
This fixes an issue with havoc not having a valid size on map().

Investigation showed that xdg_surface->current.geometry is set only by
the xdg_surface::set_geometry protocol message, which is optional. If
set_geometry is not called, then we are supposed to compute the size
from the surface buffer(s). wlr_xdg_surface_get_geometry() already
accounts for this, so we just need to use wlr_xdg_surface_get_geometry()
instead of reading xdg_surface->current.geometry directly.
2023-02-21 08:30:10 +01:00
John Lindgren
2e1c360c71 xdg: Remove unused #include 2023-02-21 08:30:10 +01:00
John Lindgren
c639cdba06 xdg: Save natural_geometry.x/y with initially maximized view
Fixes an issue where, if Thunar was started maximized, it would
un-maximize to the top-left corner rather than the center.
2023-02-20 11:50:12 -05:00
John Lindgren
74bc16910a xdg: Use view_center() for parent-relative centering
- Add optional struct wlr_box* ref argument to view_center()
- Perform margin adjustment within view_center()
- Expose view_output() to fetch parent's output
2023-02-20 11:50:12 -05:00
John Lindgren
5062c5bea3 view: Add optional output parameter to view_center()
Allows centering the view on a specific output without the workaround of
overwriting view->current.x/y.
2023-02-20 11:50:12 -05:00
John Lindgren
49c9466039 view: Tidy up view->output/view->fullscreen redundancy
A fullscreen view currently has its output specified twice by:
  - struct output *output
  - struct wlr_output *fullscreen

view->fullscreen may also become a dangling pointer if the output is
disconnected, because view_on_output_destroy() clears view->output but
not view->fullscreen.

To eliminate the redundancy and the dangling pointer, let's change
view->fullscreen to a Boolean and rely on view->output to specify the
output.

Along the way, change a few related usages of struct wlr_output to
struct output as well.

No functional change intended.

v2: Don't allow entering fullscreen on disabled output (makes
    conditions for entering/leaving fullscreen symmetric)
v3: Use output_is_usable() helper
2023-02-17 06:59:39 -05:00
John Lindgren
0ca6c4c763 view: Unify view_move()/view_move_resize()
view->impl->move() is a specific case of view->impl->configure().
To reduce code duplication, we can use view->impl->configure() for
pure moves (without resize) as well.

xwayland's move() function also possibly contained a race condition
when there was a pending resize, as it used the current surface
width/height rather than the pending width/height. This is fixed.
2023-02-16 05:21:47 +01:00
Consolatis
ecd03b70ef src/xdg.c: sync move with pending resize
Before this patch, configuring a surface with a new size,
immediately followed up by one or more view_move() calls
would move the surface to the new coordinates immediately
without waiting for the resize. This caused visual glitches
when for example dragging a maximized window: the position
would change but the size was still that of a maximized
window.

This patch fixes that by just ignoring view_move() requests
(but still updating view->pending) if there is a configure
request pending. Once the client commit comes in the new
size will be applied as usual.
2023-02-13 11:30:15 -05:00
Consolatis
06e0771341 view: make view_move_resize always work
It was not working before because in the case of wayland
we are only dealing with sizes as wayland has no notion
of a global position. A wayland client would thus not
necessarily respond to a configure request which sets
the same size again. This causes us to also not apply
a new position set in view->pending because there may
be no commit from the client in those cases.

We previously worked around this issue in some parts
of the code to check our new sizes against the pending
ones and if they were the same we would call view_move
instead. That had two issues:

- Not all parts of the code did that which could end up
  delaying the positioning either to the next completely
  unrelated xdg commit event or to the next view_move call

- The code started to repeat itself, e.g. the same condition
  with calls to either view_move or view_move_resize based
  on the result

This patch fixes it by doing the check in the xdg configure
handler instead. Xwayland is unaffected by this issue as we
are always configuring a xwayland client with both, position
and size.
2023-02-13 08:58:31 -05:00
Consolatis
f56d07aa47 Add xdg-activation protocol
This PR allows applications to activate themselves *if they provide
a valid xdg_activation token* (e.g. raise to the top and get keyboard
focus).

These tokens are given out by the xdg_activation protocol implemented
by wlroots and can be configured by the client requesting the token
in three ways:
- an "empty" token
  (apparently used to tell the compositor about "urgency")
- seat / input serial attached
- surface attached

Wlroots makes sure that
- If the client attached the seat / input serial: those two are valid.
- If the client attached a surface: that it has keyboard focus at the
  point where the request is finalized. There is a patch [1] pending
  for backport to wlroots 0.16 that also allows valid tokens when the
  supplied surface had cursor focus.
- a token is only valid for 30 seconds after being given out

The token can then be used by the client or given to other clients by
unspecified means (e.g. via environment variable or dbus) which then
may use the token on their own surface and request activation.

We only handle the actual request activation part:
- If the seat is set on the token we know wlroots validated seat and
  input serial
- Thus, if no seat is set we deny the activation request so we don't
  have windows suddenly popping up and taking over the keyboard focus
  (focus stealing prevention)
- We should also check for the surface being set but we can't do that
  with wlroots 0.16 as it will reset the surface to `NULL` when it is
  destroyed (which is something that usually happens for
  notifications). Once we move to wlroots 0.17.x we can add the
  missing surface check because it provides a `new_token` signal.
  We can use it to attach further details to the token which are then
  verified later when we decide if we allow the activate request or
  not.

With this PR in place the following setup should activate windows:
- launching an URL in foot should activate the target application if
  it is already running, foot requests a proper token and then sets it
  as `XDG_ACTIVATION_TOKEN` environment var before spawning `xdg-open`
- clicking on a `mako` notification with a `default` action defined
  should request a proper token which is then given to the application
  starting the notification and can thus be used to activate itself

This protocol is still very much in the process of being
implemented / finalized all over the place (e.g. GTK / QT / Firefox /
notification daemons, ..) but we should do our part and remove labwc
from the puzzle of potential issues causing this not to work.

[1] f6008ffff4)
2023-02-10 20:51:29 +00:00
John Lindgren
db1d6fa308 xdg: Fix positioning of initially-maximized views
- Don't overwrite pending size in map() if it was already set
- Don't reposition view in map() if maximized/fullscreen

Also, as future-proofing in case we one day allow initially-tiled views,
replace explicit maximized/fullscreen checks with view_is_floating().
2023-02-10 10:45:16 +01:00
John Lindgren
a1b5e1939d xdg: Just call view_center() now that it uses pending width/height 2023-02-09 18:26:44 +01:00
John Lindgren
0181e5f4ae xdg: Set initial pending dimensions for the view at map
We would like to use the pending dimensions in view positioning
logic, so make sure they are set early on.
2023-02-09 18:26:44 +01:00
John Lindgren
b75dbd5b38 view: Use wlr_box for current/pending geometry 2023-02-09 10:44:15 -05:00
John Lindgren
103a2a8f6c xdg: Handle corner case of move with pending resize correctly
If xdg_toplevel_view_move() is called when a resize is pending
(e.g. after xdg_toplevel_view_resize() but before handle_commit()),
the newer x/y coordinates passed to move() should take precendence
over the older pending_move_resize.x/y coordinates.

This is consistent with the logic used in xwayland.c's move().
2023-02-08 22:22:10 +00:00
John Lindgren
cfc3c93102 xdg: Eliminate redundant update_x/update_y flags
struct view's pending_move_resize.update_x/update_y flags appear to
be redundant, since we can easily determine whether x/y have been
update via a simple comparison in handle_commit().

The only corner case I can think of where this change might affect
behavior, is if xdg_toplevel_view_move() is called while a resize
is still pending (e.g. after xdg_toplevel_view_configure() but
before handle_commit()). This corner case will be addressed in the
following commit.
2023-02-08 22:22:10 +00:00
bi4k8
1b30edc778 don't set view->w and view->h when mapping xdg views
these should only be set on commit. doing so before then confuses
code that expects these fields to be in sync with the scene tree,
such as `handle_commit`.

these were only being set so that `view_center` could read them to
compute a centered position, so instead we can simply forward the
values directly to `view_compute_centered_position` and `view_move`.
2022-12-19 18:21:07 +01:00
bi4k8
272221dae2 fix cleanup issues in xdg_surface_new
`view->surface` had not been set to a non-`NULL` value here, so it
was not yet appropriate to access its `resource` member. instead,
use the resource from the argument xdg_surface.

furthermore, we need to free the newly-allocated `xdg_toplevel_view`
before error return.
2022-12-08 19:24:02 +00:00
John Lindgren
1e8b0414fe ssd: Allocate struct ssd and struct ssd_hover_state separately
- Store a pointer to the `struct view` in `struct ssd`
- Pass `struct ssd *` instead of `struct view *` to ssd functions
- Add `ssd_get_margin()` convenience function
2022-11-27 06:48:41 +00:00
John Lindgren
4da37c6532 view: Move xdg_surface + xwayland_surface to derived structs
Add xdg_surface_from_view() + xwayland_surface_from_view() accessors
that assert() the view is of the expected type before returning.

Fix a real bug in xdg.c parent_of() that dereferenced
`view->xdg_surface->toplevel` without first checking `view->type`.

The goal of the new accessors is to catch similar bugs in future.
2022-11-25 22:21:17 +00:00
Johan Malm
df7276345f view: create derived structs
...for XDG toplevels and XWayland views to only include applicable
wl_listeners for each type of view.
2022-11-25 14:47:53 +00:00
John Lindgren
c536ee9d96 view/ssd: Move view->margin to view->ssd.margin 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
John Lindgren
2995d0e8e0 view: Fix positioning of initially-maximized XWayland views
map() in xwayland.c called ssd_create() but did not call
view_apply_maximized_geometry() afterward, resulting in the
decorations being displayed off-screen.

Rather than calling view_apply_maximized_geometry() in more places,
let's reuse the existing call in view_set_decorations(), and extend
ssd_update_geometry() to call ssd_create() when needed.
2022-11-20 19:10:05 +00:00
Johan Malm
e45e2c7e60 Fix coding style 2022-11-03 23:01:52 +01:00
John Lindgren
a54d378e6c common: Add znew/znew_n() macros 2022-09-18 15:25:19 -04:00
John Lindgren
cb40cdc36c common: Add additional memory utilities (xzalloc() etc.) 2022-09-17 10:57:30 -04:00
Consolatis
bc4ce1bd5d src/xdg.c: Only call view_moved() when required 2022-09-08 01:32:22 +02:00
John Lindgren
b8096b1bab view: Call view_moved() immediately after map
At least for XWayland surfaces, handle_commit() is not always
called after map(), and as a result, the scene-graph node is never
positioned.

Not sure 100% if the same can occur with XDG surfaces, but the
extra view_moved() call should be harmless, so add it there too
for consistency.
2022-09-06 13:39:22 +02:00
Johan Malm
52d1e32b59 view: view_move() s/double/int/ for x and y 2022-08-18 19:50:25 +01:00
John Lindgren
065c37d3f5 xwayland: Process move-only client configure requests more quickly
For a move-only client configure request, treat it similarly to
view_move() by updating the scene-graph immediately, rather than waiting
for handle_commit().  Move-and-resize requests are handled the same as
before.

This (mostly?) fixes the glitchiness that was noticeable when dragging
an undecorated XWayland window (e.g. Audacious in Winamp mode).

Also:

- Reduce some code duplication in handle_request_configure() by
  simply calling configure(), as suggested by @johanmalm in #428.
- Factor out common logic after a move and/or resize into view_moved().
2022-07-18 22:06:12 +01:00
Consolatis
09915b8f43 src/ssd/ssd.c: Keep view->margin in sync when toggling decorations
Fixes #409
2022-06-30 06:45:18 +01:00
Consolatis
8c5157a098 workspaces: Wire up workspaces 2022-06-15 22:26:21 +02:00
Consolatis
2ed7a10779 Chase wlroots: every scene_node parent is now a tree
Chases wlroots ccd0f85c2a36308e35b153c7f9653abac7659af3
wlr_scene: Only allow parenting on a wlr_scene_tree
2022-06-07 07:13:37 +01:00
Johan Malm
a1cf5b3e96 xdg-shell: set view position before view_maximize()
...on first map so that view->unmaximized_geometry is known even if an
xdg-shell application started in maximized mode.

Fixes issue #305
Reported-by: @01micko
2022-04-28 22:29:10 +01:00
Consolatis
73930f7e0f view: Refactor view destruction some more 2022-04-23 08:59:06 +01:00
Joshua Ashton
d0b9680d00 view: Refactor view destruction
Consolidates all of the view destruction code for xwl + xdg into one function.

Fixes several notable bugs along the way:
  - Fixes a crash when alt tabbing when a selected view gets destroyed.
  - Fixes the OSD not updating to reflect a view has been destroyed.
2022-04-22 01:58:52 +02:00
Johan Malm
b27955050f xdg-shell: remove view->padding
With the wlroots scene-graph API, the padding variable is no longer
needed for windows with Client Side Decoration (CSD).
2022-04-21 20:21:36 +01:00
Johan Malm
5b34c81768 Fix trivial coding style breaches 2022-04-04 20:53:36 +01:00
John Lindgren
8e1f115486 cursor: Fix "jumping opposite edges" issue when resizing
Commit 08c537e ("xwayland: Honor size increments from
WM_SIZE_HINTS") adjusted only the window width/height according
to the size hints.  If resizing from the top or left edge of the
window, we also need to adjust the window position to keep the
bottom or right edge from jumping around.
2022-04-04 17:28:52 +01:00
Consolatis
befe66d93f cursor.c: Keep sending adjusted motion events while button is pressed
This allows to keep dragging a scrollbar or selecting text even when
moving outside of the window. Fixes #241
2022-03-21 17:56:48 +00:00
Johan Malm
7a708a0dc9 xdg: set node position on commit and configure
To avoid incorrect view position, for example on initial placement.
2022-03-06 17:12:00 +00:00
Johan Malm
30298228e3 Rename node-descriptor.c to node.c
...in anticipation of adding helpers like node_view_from_node()
2022-03-02 21:07:04 +00:00
Johan Malm
bd9ac3478a Remove src/damage.c 2022-03-01 20:54:52 +00:00
Johan Malm
2891ff245e Add node-descriptor for wlr_scene_nodes
Support identification of wlr_scene_node role to enable simplification
of codebase including the avoidance of iterating over lists of
layer-surface, menuitems, and so on.

Use node-descriptors for xdg toplevels and popups
2022-02-26 22:35:51 +00:00
Johan Malm
f4c9d1ba9f Set node position in xdg/xwayland commit handlers
...in order to sync resize/move events to avoid left/bottom edge wobbling
when resizing with top/left resize edges
2022-02-23 22:39:57 +00:00
Consolatis
29021dad6a xdg/xwayland: Do not destroy scene node on unmap
This prevents segfaulting when unminimizing
2022-02-23 21:47:01 +00:00
Consolatis
5862b65f89 Convert SSD to scene nodes 2022-02-23 21:47:01 +00:00