* windowstate/layerstate: don't dynamic_cast a view's self-ptr during destruction
The view.destroy listeners erase_if'd their containers by evaluating
dynamicPointerCast<IView>(x->m_self). Since the event is emitted from
~IView, the matching view's derived member m_self is already destroyed
by then, so reading it is UB. Compare control-block identity via
PHLVIEWREF{x} instead, which never dereferences the dying object.
* iview: remove pointless destroy listener
CWindow/Layers calls removeSafe in their own onDestroy,
the best way to avoid buggy code is by simply not doing it at all :)
earlier codex complaint, if empty fifo commit happend but contained
feedbacks it was silently dropped. also at the same time the only time
we should discard current feedbacks if there are any is when a new
buffer appears.
add a presentation bit flag, set it in onGetFeedback.
* Revert "presentation: revert "associate feedback with committed surface state (#15243)""
This reverts commit 4a753eaa03.
* presentation: fix WP locks and discard failed draws
the reason it stopped working is last change that PR
did was moving from raw ptrs to UP's with WP's but tried to .lock() the
WP, we cant lock a WP that points to a UP.
also ensure all draws that isnt visible or simply failed creating
texture or invalid sizes discard in elementrenderer. and all others
present.
* frame: fix frame scheduling being skipped or one vblank off
in renderer we need to check if we have pending damage, needsFrame can
be cleared by commits that was done while pageflip was in flight.
m_renderingActive also needs to be set after actually comitting.
add a commitTimingTarget that we check against on presentation otherwise
the committiming timer runs only on duration and might miss the upcoming
vblank period as in always being one vblank late. and use the timespec
we get from presentation.
* frame: skip early release on invalid timestamp
skip early release on invalid timestamp, and rely on the timer timeout
if missing.
makes the presented signal emit a std::optional timestamp instead.
* frame: only early release for single output
if the surface entered multiple outputs, we cant early release it
because they flip at different times and might make it release way
before the flip of the other monitor.
* frame: anchor commitTimingTarget to the client timestamp
get the absolute target directly from the requested timestamp.
reset commitTimingTarget if delay is 0, and reset it in SSurfaceState
reset.
* frame: fix codex complaints
use fromTimespec so "C++ steady-clock epoch does not exactly match
CLOCK_MONOTONIC" doesnt occur. unify the timespec code in both
monitor and commit timing protocol. always send the timespec on monitor
presented signal.
* tokens: expire one shot initial workspace tokens
tokens are only removed once a window maps, so things like
xdg-desktop-portal got the 1337 month duration token added and always
first launch in the wrong workspace. check PINITIALWSTRACKING and if
mode 1 just give them a 1 second token. like other code paths does.
* tokens: increase timeout to 10 seconds
increase the timeout to 10 seconds, slow launching things like krita is
above the 1 second we have now. if 10 seconds is to much it can always
be fine tuned lower later.
* tokens: add a config option for timeout
add initial_workspace_token_timeout as a config option to be able to set
the default timeout for the initial workspace tracking token.
* tokens: rename timeout to actually timeout
urgl, to much going on at the same time. TIMEOUT certainly makes more
sense for an timeout.
* desktoå/view: fix IView virtual inheritance and erase_if ptr
CSubsurface and CSessionLock inherited IView non-virtually while
CWindow/CLayerSurface/CPopup inherited it virtually.
erase_if compared event.address with the derived complete object
pointer. under virtual inheritance those addresses differ.
* desktop/view: use dynamic casting over static casting
change to dynamic casting instead of static casting.
* better
* more better
more better is more.
---------
Co-authored-by: Vaxry <vaxry@vaxry.net>
* screenshare: don recopy a dmabuf while fence is pending
copy is called for every pending frame on the output commit. and output
commit fires on any output commit not just buffer ones. so the fence can
easily be not signaled yet.
* screenshare: erase done frames too
erase done frames from m_pendingFrames to avoid growing to huge
numbers. a finished frame copied/failed/session gone is skipped by the
copy but was only erased once it expired. a slow client could let the
vector grow.
after 254d6bae77 fadeouts now live in
fadingOutState() instead of the normal containers, so add SC_FADEOUT and
iterate the new fadingOutState() and block solitary for fadeouts.
glDrawBuffers is per FBO state, but it was only set when mirroring was
first enabled on whatever work buffer happened to be mainFB that frame.
since work buffers rotate other FBO's kept default single draw buffer.
move the draw buffer selection into internalAlloc so it always follows
the mirror attachment.
when lease is destroyed the destroy listener nullptr deref m_lease, and
all it uses it for is logging the fd number. capture the fd by value to
avoid crashing.
* dwindle: avoid crashing on expired weakptr
pTarget can be expired when toggling a tiled window to floating during a
drag move that triggers removeTarget -> recalculate -> calculateWorkspace
before the dead node has been cleaned up.
* hyprtester: wait for enabled monitor
without waiting for enabled monitor we can race the tests and call focus
on non enabled monitors.
* popup: fix crash on destroyed xdg surface resource
the xdg_surface can be destroyed before the xdg_popup, so CPopup::onDestroy
hasnt run yet and the popup is still in its parents m_children with m_wlSurface set.
if guard it in popupTreeExtents.
* popup: safe guard bad resource
popups can be fading out while the resource is dead, ifguard it and
return m_lastPos if thats the case.
* groups: add groupbar disable_when_only option
* groups: improve `groups` test
`groups_disable_when_only` test fails because it checks windows sizes after
`disable_when_only` option changed. Changing option currently don't
trigger window size update.
Same problem with `groups` test, but it worked because it or:
- didn't checked window size after changing option.
- called `hl.dsp.group.toggle()`, which trigger size update
- at the begining set `enable = 1` while it `== 1` by default
Now it fails too :D
Seems it works in usual Hyprland usage because:
- `CHyprGroupBarDecoration::draw` calls
- `g_pDecorationPositioner->repositionDeco(this)`,
which will invalidate cache and update sizes.
* groups: fix `disable_when_only` and `groups` tests
REFRESH_LAYOUTS is not required 'cause REFRESH_WINDOW_STATES will
trigger update of window position too.
* groups: fix groupbar drawing
use the current row and the SHM stride when calculating copy offsets,
the previous code calculated the copy offset incorrectly by always using
the first damaged row and by assuming each row as only as wide as the
damaged region.
* config: fix initial workspace tracking
previous refactor over to Executor missed m_isLaunchingExecOnce meaning
any hl.exec_cmd(hyprlauncher) got the token of 1337 month duration at
the first launched workspace, so the initial launch of things gets that
token and opens on the wrong workspace.
add m_isLaunchingExecOnce back, and make getHyprlandLaunchEnv a member
of CExecutor aswell.
the needle counting also missed the final partial chunk if the read
failed to read 512 bytes but still read a chunk.
* hyprtester: fix monitor rule
ID's are unreliable. try to parse it directly from name.