Skip to content

Add threaded canvas item#131

Closed
cmeyer wants to merge 8 commits into
nion-software:masterfrom
cmeyer:2026-04-06-update-and-layers
Closed

Add threaded canvas item#131
cmeyer wants to merge 8 commits into
nion-software:masterfrom
cmeyer:2026-04-06-update-and-layers

Conversation

@cmeyer
Copy link
Copy Markdown
Collaborator

@cmeyer cmeyer commented Apr 9, 2026

  • Add method to access canvas item owner thread.
  • Modify batch update to only do update if actually updated.
  • Remove unused/non-functioning mouse tracker support.
  • Remove unused ui_interaction tracking.
  • Remove inconsistently used mouse tracking hack.
  • Restructure canvas item hierarchy using base container.
  • Add threaded canvas item to do layout and repainting in a thread.

Each commit has been audited by copilot.

cmeyer added 7 commits April 8, 2026 14:34
This hack is being removed because it is not compatible with upcoming
changes. The hack was used to work around a problem of not receiving
mouse exit messages in canvas items. This seems to have been fixed via
other mechanisms.
This eliminates the assumption that the 'root container' is a
RootCanvasItem; and instead introduces a base container protocol
for more flexibility in how canvas item hierarchies are contained.
@cmeyer cmeyer changed the title 2026 04 06 update and layers Add threaded canvas item Apr 9, 2026
Copy link
Copy Markdown

@lisham2000 lisham2000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment landscape makes the code really easy to follow and decisions are clear

Comment thread nion/ui/CanvasItem.py
super().__init__()
self.__threaded_canvas_item = threaded_canvas_item

def _updated(self) -> None:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should _updated call update. That seems wrong to me. If it is correct, then I think a comment is needed to explain it to anyone else who looks at this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read this as it trying to chain the updates, so _updated is called after an update on this object is complete, then it chains down to start the update on the child object. I had assumed this was intentional to do it's own update before the child update.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add a comment about this. Basically there are updates coming from canvas items "below" the threaded canvas item, and updates that need to go to canvas items "above" the threaded canvas item. update is a request from anywhere to update the canvas item on which it is called. _update is called when the item has actually been updated. In this case, it is used to tell the canvas items "above" that they now need to update. Explained another way: the canvas items in the thread get updated; when the top level item (the wrapper) receives _updated message it will have a valid drawing context for everything "below"; now it needs to tell the threaded canvas item that it needs to update so that it gets redrawn using the drawing context that just became became valid.

Comment thread nion/ui/CanvasItem.py
traceback.print_exc()
traceback.print_stack()

def mouse_clicked(self, x: int, y: int, modifiers: UserInterface.KeyboardModifiers) -> bool:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the benefit of having a public function (e.g. mouse_clicked) that just passes the arguments to a private function (e.g. __mouse_clicked) over just a public function?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit subtle, but my intention is to merge Layer/Root/Threaded canvas items. This is separate because I initially did that but backed away since it was too many changes at once. With the 'root' variant, the mouse events (and other events) come from the widget rather than the inherited mouse methods. So I left them separate in this version.

Copy link
Copy Markdown
Contributor

@Tiomat85 Tiomat85 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok, though I am a bit unclear on _request_base_focus.

@cmeyer
Copy link
Copy Markdown
Collaborator Author

cmeyer commented Apr 10, 2026

Looks ok, though I am a bit unclear on _request_base_focus.

Me too. I left this alone to match the existing code in Layer/Root. I expect to refactor this in an upcoming PR.

@cmeyer
Copy link
Copy Markdown
Collaborator Author

cmeyer commented Apr 10, 2026

Merged. 7652233

@cmeyer cmeyer closed this Apr 10, 2026
@cmeyer cmeyer deleted the 2026-04-06-update-and-layers branch April 10, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants