Solved Switch layout issue in R21.115


A customer brought to my attention an issue with one of my plugins, related to switching to a layout containing the plugin's GeDialog with GeUserArae as a docked window.
At first I could not reproduce the issue on my system, but later one noticed that the issue did only appear with layouts created with R21.115
Issue does not manifest when using in R21.115 layouts created with R21.026.

I created

(3min21, no audio) of the issue showing R21.026 and R21.115 using a "dummy" plugin with implementation reduced as much as possible to only be able to reproduce the issue, but without any purpose for using the plugin itself.

I will provide the plugin, layouts, and source code via e-mail, referring to this thread (topic 12233)
Hopefully further discussion can be performed her in this thread.

Hi Daniel, thanks for reaching out us.

We're investigating the issue and we'd like to know if you had any special screen scaling setting when the video was recorded (maybe higher than 100%)


@r_gigante said in Switch layout issue in R21.115:

had any special screen scaling setting when the video was recorded (maybe higher than 100%)

No scaling, only the default screen settings of 100% on a 1920x1080 screen.

Hi Daniel, I've been updated from our developers about the issue.

Actually in MyDialog::InitValues() you're implicitly modifying the layout during the layout-switch and this is likely to be the root cause of the issue.

I suggest to decouple the CallCommand during layout switch queuing a job on the main thread queue so that the layout is not modified during the switch.

   // Do not modify the layout during switch! Therefore enqueue a job on the main thread which is executed later.
   }, maxon::JobQueueRef::GetMainThreadQueue()) iferr_return;

Probably not the nicest solution, but without a better understanding on what/why your're doing this, this circumvents the problem.
Another note is that in MyUserArea::DrawMsg you're using a BaseObject pointer in an if statement which is not recommended. Rather use a BaseLink to be sure that even whatever happens to your BaseObject the BaseLink can not fail.

Cheers, R

Hi Riccardo,

Thanks for the update.
Could you please explain what you mean by "modifying the layout"?
The one thing I was trying to achieve was to redisplay the active node into the Attribute Manager.
I had noticed that when one saves a layout it also stores the current Attribute Manager's mode.

Say, the user has selects a polygon object, the Attribute Manager will display the object's attribute.
Then the user saves the current layout. When later the user switches back to this saved layout, the Attribute Manager will switch to Object Mode.
But I argued that when the user had selected a tool prior to switching to the saved layout,
he/she might want to have the Attribute Manager show the selected tools' attributes after switching.

This is what I tried to achieve. When my description tool is active, and the docked dialog gets initialized
I would try to show the active tool's node attributes in the Attribute Manager.
Following is what actually is meant to be done by the CallCommand

BaseSceneHook* bsh = doc->FindSceneHook(MYSCENEHOOK_PLUGIN_ID);
if (bsh)
	MySceneHook* msh = bsh->GetNodeData<MySceneHook>();
	if (msh)
		GeListNode* nodedata = msh->GetNode(MYNODE_PLUGIN_ID);
		if (nodedata)
			// activate our node
			// 1. The description tool is just a decoy for the viewports,
			//    we don't want any other native tool being active.
			//    The user sees our description tool as the active one,
			//    but the real "tool" is our node with its attributes
			//    to perform actions inside a GeUserArea
			// 2. As the node is the actual tool for the GeUserArea,
			//    we want to display the node's attributes in the Attribute Manager,
			//    and this when our description tool is active and it isn't
			//    the item currently being displayed

			AutoAlloc<AtomArray> items;
			ActiveObjectManager_GetObjects(ACTIVEOBJECTMODE::NODE, items);
			const Int32 idx = items ? items->Find(nodedata) : NOTOK;
			if (idx == NOTOK)

Is that what you mean: changing the item which gets displayed into the Attribute Manager
is "modifying the layout"?

As for the BaseObject pointer in the MyUserArea::DrawMsg. This was only to try and keep the code small, as the whole demonstration plugin was already becoming quite large.
In the actual plugin I do actually get the active object. I had tried in the past using BaseLink, but that meant I also needed to keep that BaseLink in sync whenever a different object became the active one.

I further investigated the reason why I originally did set the Attribute Manager as a result of the GeDialog::InitValues(), but couldn't really find an answer except to assume this was just a plain bad design that grew over time. In the meantime I have reworked the whole thing, and don't actually see the need to set the Attribute Manager to begin with. Thus avoiding the need to enqueue some job on the main thread.

I am OK with the outcome that the whole issue is just caused by a bad design I had come up with ...
Still I was wondering why my original implementation (which worked from R16 up to R21.026) suddenly was broken with R21.115. This is the reason I started this topic here, assuming the change of behaviour was unintentional (a bug).

Hi Daniel, the reason why it worked "as expected" on older revision was by pure chance - as much as it was for the Redraw thread.