Fix: Interactive Docking modal operator re-run glitch #126379
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Code Documentation
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#126379
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "Brainzman/blender:fix-bad-docking-modal"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The following is a weird bug, with an even weirder and (temporary) fix.
Bug Description
The main interactive docking modal operator (
SCREEN_OT_area_join
) can sometimes be wrongly re-run by the Window Manager modal handler after finishing when opening/closing windows. This is due to the modal handler interpreting changes in the current context window as the operator being freed. (see the condition in wm_event_system.cc). This causes the operator to get in a broken/in-between state, where the cursor randomly changes and different areas get random docking highlights and hover behavior.Demo
Fix
As the check happens in the modal handler, my original fix idea was to try to fake it, by re-overriding the original window back into context, see this diff:
This however, does not work when windows are being closed for their areas to be merged into other screens, as seen towards the end of the demo, as they have been freed and naturally cause null derefs in
window_set
.I thus went for the alternative (and very hacky approach) of tagging the operator via a fake
op->customdata
address, acting as a value, a hack possible since the modal handler doesn't clear it between runs. This let the modal function check if it's being wrongly run again, and finish gracefully. See the content of this PR.This took me quite some time to debug and figure out. And this is certainly not a proper fix. It (maybe?) could be merged in to let user better test the experimental feature. But a proper fix would be to either :
0c3abf0a9f
to84cda54113
@Brainzman
I have no doubt there is an error here, but I've been unable to reproduce what you show in the capture. Are there reproducible steps to take that causes this?
@Harley I can still reproduce the issue on the latest main, attached you'll find a .blend file you should be able to open with Load UI to get to the starting point of the following demo.
repro.blend
The problem happens when drag-and-dropping a window into another one to merge their editors. It happens every time if the window has just been created/teared off, and may or may not happen if multiple actions like selecting other windows or switching apps have happened since creating the second window (as seen in the demo), in which case, the window can just be teared off and immediately drag-and-dropped back in to reproduce the bug.
I don't know if the .blend file window placement will still hold on Windows, and the fact that I have multiple monitors plugged in could also mess things up a little. If that's the case, you can reproduce it manually by just opening two additional child windows like I did, window size/placement doesn't matter in my tests.
Note that the issue could also be macOS only, I'm curious to know if anyone else could reproduce it on macOS (perhaps @Alaska if you're interested?)
I can reproduce the issue here with latest main on my Mac and on Windows with the steps shown in your video with the file attached to your comment.
If it helps, tests were run on a 2560x1440 screen with 100% scaling in both cases.
Oh, I can (finally) recreate this by using this blend. Thanks!
@Brainzman
I'm sure this is separate issue, but I'd love for you to confirm that you see the same thing....
When I launch that "repro.blend" on my computer I get three windows, a main window on my main monitor containing the usual default editors. On my second monitor (to the right) there are two windows, one an Image Editor and the other a Timeline.
It is the Timeline that is the most interesting. Its left edge is at that monitor's left edge, actually just one pixel to the left of it. If I drag to that one from either other window it seems at first that it will only dock to the entire window. But that isn't really it. The tooltip info normally shown at the mouse cursor is not shown. That has to be shown somewhere so it is probably out of window bounds.
If I move that window even slightly it works correctly. While at the edge and it not working, the value for
x
inarea_docking_target
has a value that is not in that monitor. I drag into the very left part of where I would normally get "10" or so, I get 1400 or so - a value that would be inside the left monitor,But I do not think this is related to the calculations in
area_docking_target
. So far I think "win2" is not incorrect. But still investigating...@Brainzman
Okay, that sample blend of yours was really interesting...
The "posx" and "posy" of the window containing Timeline is not correct. If you move or resize that window then Blender asks ghost and then corrects that window's position and size using
wm_window_update_size_position
.When creating a new window that same function is called. But when restoring windows from a blend then that function is not called. I'm assuming that this window might have some other position but it placed where it is based on some limitation and those win members are not set right.
I can get that sample blend to work correctly with the following changes:
Do you mind giving that a test before I make a PR?
@Harley Ah! Funnily enough I was just about to comment on not being able to reproduce the bug, even after debugging the posx/posy and sizex/sizey values in
wm_window_ghostwindow_ensure
, but suspecting the problem was close to this area.I'm not completely able to fully dive into this right now, but a rough possible cause from intution, is that similarly to the previous docking bug we had on macOS, we're missing a conversion from native pixel/retina coordinates (so basically *2 or /2) which could make the relative window coordinate double or halve. I would need some to do some additional experiment to confirm this theory, but as I'm not able to reproduce this bug at all on the macOS machine I created the file one, I would guess that it's at least roughly related to this area (unimplement macOS window coordinates shenanigans). I'll try to open the blend on my Linux workstation tomorrow to see how it reacts, and depending on this I'll see if I can properly debug my way to the source of the problem.
Overall, while this is definitely one weird edge case, that's also definitely the kind of problems that we would need to fix by overhauling macOS window coordinates and adding proper multi-monitor support as we previously dicussed. Potentially, we could also eliminate an entire possible class of bug if we properly abstract the fact that macOS (and possibly other future GHOST backends) uses a different, native x2 pixel size coordinate system instead of having to manually insert
getNativePixelSize
in hard to predict places. This is definitely something that's on my todo and I hope to be able to concentrate on in the upcoming months. We even got some related user bug reports since then (see #126410 or #127038)@Harley And regarding the patch you included, I can confirm that it run fines, but doesn't affect the layout restoration on macOS (possibly because the saved coordinates are already correct at this native pixel size like I suggested above).
However, as I said above, there might be a less work-aroundy way of fixing this issue (especially, since this seems more like macOS saving bogus coordinate than the WM doing something wrong upon loading the UI), I'm making quite a lot of assumptions here, which might be completely wrong since I can't really cross-check anything right now, but I'll try to look into the problem from a more macOS specific window coordinates point of view asap.
The odd thing here is that is does just seem like a bug.
wm_window_ghostwindow_add
currently does callGHOST_GetWindowState
but then only updates the win's sizex and sizey. Seems a bit odd to do that and not also update posx and posy.wm_window_update_size_position
does both, but this isn't called when loading windows from a blend.It was a pain to find it. In a nutshell I had set a breakpoint near the bottom of
area_join_cursor
(currently line 3900) where it returns a "move_cursor". With your blend file this is hit the moment you drag into Timeline from Image Editor. And here I noticed that jd->win2 was the correct window, but the positions of it were wrong. win->posx = 449 while win->posy = 142, which are completely unrelated to the position of that window. And doing anything with it instantly fixed those values. And of course with those values wrong the calculations for where in that window you are dragging is also bogus.@Brainzman
For this specific issue, of the operator being re-run after a window is closed, I think this might be all we need:
cee80562d6
todb9a24d64d
@Harley
Taking a better look at the overall window restore logic your patch seems to actually perfectly address the issue, as unlike I originally thought above, window size/position adjustments are supposed to be performed on load, that's a very nice catch, and I would guess this fixes a more general issue of blend file not properly restoring when saved/restored at different native pixel sizes.
Ooh that's indeed a nicer solution than the hack I propose in this PR. However, I think it would still be nice to keep the operator as is, and try to instead fix the problem in the window manager. Like I said in our last meeting, this operator is not technically doing anything wrong, and since this is behavior that could theoretically be implemented by a user-defined Python operator, or a future screen/WM C++ modal operator for that matter, we also have a pretty bad, and veryy confusing general modal operator bug on our hands.
As such, and as I suggested as one of the possible solutions of this PR, the "proper" fix would then be to improve the condition in wm_event_system.cc by adapting it to actually check if the loaded blend file changes (as the comment above the condition suggests). I'll try to write up a solution for this soon, and I'd also first need to reproduce the reason why this workaround is in place in the first place (probably via the addon suggested in the comment). Also CC @ideasman42 I'd be interested to get your view on this.
Also, thinking twice about this, if we're in a rush to fix this issue for the area docking release, we might just as well merge this PR with your patch as a temporary fix, and make another PR that properly fixes this issue on the WM side later. I updated this PR with your patch in that sense.
@Brainzman
It looks harmless at least so will probably do a bit more testing and do that soon.
I've just had no luck trying to fix this in that behavior in wm_event_system.cc.
That makes sense. This check for WINDEACTIVATE is pretty harmless and should coexist (if it has to for a while) with a change to wm_event_system.cc.
Thanks so much for all your help with this.
@blender-bot build
WIP Fix: Interactive Docking modal operator re-run glitchto Fix: Interactive Docking modal operator re-run glitch