Implement the Scaffold layer for core and dummy#4382
Conversation
|
@freakboy3742 As I've aced my last final exam in school, I've began to work on this more. I'm mostly done with core now but have a question about tracking app and window on Widget.
The reason I'm talking about this is that I'm thinking of taking a more simplified approach to getting the scaffold — while it is possible to handle it in a similar manner as window and app tracking, i.e. assign |
The main reason I can think of is that a widget can exist without necessarily being part of a window layout. I don't recall if there was a historical reason why a widget needed to be assigned to an app explicitly so that some "before the widget gets assigned to the window" handling could be done - but it's entirely possible that reason no longer exists (or never existed and we were over-complicating things).
Proxying scaffold retrieval through the window makes some sense - my only concern is whether that will remain accurate in future in more complicated situations where a second-level scaffold is allowed (e.g., the situations where tabs in an OptionScaffold themselves have scaffolds). However, that might be worth deferring to the future when we actually have that problem - as long as a widget can get it's scaffold, we're not saying anything about how it determines that value, so if it needs to change in future, it can. |
Well... SidebarScaffold in OptionScaffold having a side pane is effectively broken in older iOS version we need to support—as discussed in #4299... But that may as well be a separate issue. But since I already suggested getting App from Window, we can take this a step further: track scaffold, get window from scaffold, and get app from window... this is going to make the codebase a lot easier to understand and will alleviate any nesting concerns. I'll try to implement that as part of this PR on my next cycle.
The set behavior seems publically documented -- bug in docs?
|
Not so much a bug as something that is difficult to document. It's traversing the gap between "things that need to exist and be documented for internal use", and "things that the end user actually needs to care about". It's not wrong - that is how the setter works. But as an end user, you shouldn't ever need to care. Can we clean this up? Almost certainly. |
|
After thinking about this more: I don't think I'm going to try to refactor window and app in this PR, and I'm just going to track scaffold like we track Window and App previously. I'm making this decision because there's a widget registry for each window... so it's going to be hard to move things around (one can of course make a registry for each scaffold but doing all the bookkeeping and restructuring of getting widgets in each object is going to scope creep.) TL;DR I'm going to track scaffold for each widget the same way app and window are tracked, to leave the door open for future nesting if needed and avoid scope creep. |
|
@freakboy3742 I'm done with core, dummy, and their tests; dependabot PRs are blocking CI, but I've manually tested with macOS 3.12 and 3.13 on my mac and they all work well. I would appreciate a partial review of those parts. |
|
Note: After the latest commit this is still [1] ready for a partial review of core, dummy and their tests; I merely used scaffold to consistently interact with the layout code. [1] — my last message sent prematurely; I've edited it to indicate this was ready for a partial review, but turns out I missed a change. |
|
@freakboy3742 Touching base on this one---to be explicit, I need a partial review of core/ before continuing; sorry for my vague wording. |
freakboy3742
left a comment
There was a problem hiding this comment.
From an initial light review - this looks like it's on the right track. The general shape of the Scaffold core API looks right; a few comments inline, but nothing too significant at this point. I'm sure more details will fall out of the iOS, and macOS backends.
The only detail of note at this point is that if preparatory work is needed (like the "has-a" vs "is-a" relationship for Android and Windows containers, that should be pulled out as a precursor PR. We can land that work indpendently, which makes it a lot easier to evaluate the actual scaffold changes from other housekeeping.
Removed duplicate imports of Scaffold and BaseScaffold.
Added _create method to Scaffold class to instantiate a new Scaffold.
3421252 to
dc0cd0a
Compare
|
@freakboy3742 This is ready for review now to merge into scaffolds branch. I've fixed up all the issues you mentioned and moved Android and WinForms priming to #4484. FTR: As discussed over discord and elsewhere:
|
Co-authored-by: Russell Keith-Magee <russell@keith-magee.com>
Co-authored-by: Russell Keith-Magee <russell@keith-magee.com>
Refactor test_set_scaffold to include app and window parameters. Update test_set_scaffold_with_children to ensure child widgets are assigned correctly to scaffolds.
Removed unused child widget instantiation in test.
Removed the scaffold property and updated set_scaffold method to set the scaffold directly.
Refactor content property handling in Scaffold class to use BaseScaffold's implementation.
Removed unnecessary constructor in Scaffold class.
Removed the 'window' parameter from the test function.
There was a problem hiding this comment.
The real place this triggers for me is the repeated
widget.app = app; widget.window = window; widget.scaffold = scaffoldpattern of logic. When a widget is assigned to a scaffold, there's only one possible window and app, so 3 assignments shouldn't be necessary.
One thing I've thought about is making app a dervied property from window and window a derived property from scaffold.
The issue preventing this was that the window kept a widget registry... so that needed to be handled separately, and we'd end up in a situation where we technically can make app derived... but is app derived from window or scaffold, if the scaffold is not attached to a window? I agree this is a relatively contrived case and that there's probably some opportunity for cleanup that can make this work easily, but I didn't want to think about the moving parts (pun intended) involved here for the sake of pragmatism.
There's also the need for test updates to explicitly associate stuff with a window instead of setting the window property, which is a lot of work. So I left it out.
I've made the requested changes that I agreed with, and am now waiting on some clarifications and discussions I've posed inline.
(I also apologize for replying to comments individually inline, as bunching them requires the Files Changed page which was quite difficult to go through. I replied "Done" to some things as I've just read that it was not permissible to click Resolve Conversation myself, so that it's clear what is still ongoing to be discussed here; let me know if this is unnecessary.)
EDIT: Also CI seems to be broken. I pushed very often to check if it was intermittent, but seems like it's a permanent issue now. I suspect it's the vcs_versioning fiesta -- can you merge main into scaffolds? After that, let me know and I'll merge scaffolds into this PR to see if things pass.
And of course, thanks kattni for handling the PR routing.
| assert child3.scaffold is None | ||
|
|
||
| # Assign the widget to a scaffold | ||
| widget.scaffold = scaffold |
There was a problem hiding this comment.
Since we're going to track app and window and those are tracked separately with scaffolds, I'm going to be refactoring this into scaffold.content (and similar places).
I'm ok to leave this as a pragmatic commission for now, and maybe address this in future as an independent cleanup pass that clarifies the API surface of widget/window to remove setters of things that users shouldn't be setting.
Done - and I've merged this PR as well. |
Addressing this one specifically: Replying to comments individually inline is fine - if you're responding to specific feedback about a specific line/section of code, the thread coming off that feedback is the right place to be posting. The fact that each "comment" turns into a separate email isn't a concern - yes, it's more emails, but that's not the thing that is a problem. Broadly speaking, a thread on a single line/section should be a comment from A, then a reply from B, then a response to the reply from A, and so on. If ABABAB happens on multiple different lines of code, that's fine (and expected). An occasional ABBA is occasionally going to happen; that's OK as well. The problem is when the thread is ABBBBBBBBB - that's an indication that B hasn't thought through what they want to say before responding. As for posting "Done" - that's fine (and can even be helpful if it's not obvious that whatever has been requested has actually been done. I will sometimes use a 👍 on a review comment instead of an explicit "done", unless there's some specific interesting detail about what "done" means (e.g., "I've done what you've asked, but it had this other consequence that might not be obvious") |
Thanks for being explicit with this concern; I understand now that the issue is avoidng unneccessary noise in terms of monologue, and appreciate the time you have taken to make this clear. |
|
I'm pretty sure I addressed most things here except for the double-content-setting issue, which is not a blocker; so I'm asking for another review now. |
freakboy3742
left a comment
There was a problem hiding this comment.
Getting close to mergable; a couple more cleanups flagged inline.
|
Thanks for flagging the issues, and for your patience on working this another round. I've asked for another review after fixing them. (I've actually managed to figure out why ruff isn't sorting init.pyi: It's explicitly flagged as isort: skip at the top. I replied inline about this, but since it was on a resolved conversation, I'm putting it here to increase visibility. I do not intend, however, to resolve this issue right now, as it is orthogonal to this PR as long as I sort carefully manually.) |
freakboy3742
left a comment
There was a problem hiding this comment.
One last tweak, but I think this is good enough to land as a base for actual platform implementations.
|
Nice catch — thanks! FWIW: I may choose to focus my free time during the next few days on a personal app so I may not be able to start backend implementations as soon as you might've hoped (and on top of that, I'm traveling). All that is to say, feel free to start on some backend implementations yourself if scaffolds are a big personal priority to you. |

Refs #4298.
This is a work-in-progress implementation. A broad checklist that I try to go off of:
create_menuonto all scaffolds. But this will be handled later.set_scaffoldcontentand_scaffoldPR Checklist:
Assisted-by: GItHub Copilot; Google Gemini, ChatGPT (latest web)