I'd like to change Desktops depending on context. For example, if I'm inside a SOP network, I'd like Houdini to automatically switch to Desktop A. If I then dive into a Copernicus network, I'd like it to automatically use Desktop B. If I enter LOPs, let it switch to Desktop C. And so on.
Is this possible?
Is it possible to auto change Desktops depending on context?
5318 24 5-
- ajz3d
- Member
- 654 posts
- Joined: Aug. 2014
- Offline
-
- jsmack
- Member
- 8177 posts
- Joined: Sept. 2011
- Offline
-
- ajz3d
- Member
- 654 posts
- Joined: Aug. 2014
- Offline
Yes, so I've noticed. I must say I find it annoying when after switching desktops I'm taken someplace else in the network. But that's another pair of shoes.
Anyway, I'm using different desktops for each context, with completely different pane layouts, network viewer settings, network snapping and other stuff. So I wish there was some way of forcing Houdini to automatically switch desktops, even if it involves some reasonable hacking (of
If it's really impossible, then what I'd like to be able to do at least, is to create a radial menu with most used desktops, so that I could easily access them when necessary. But, I searched through HOM documentation (particularly the
Anyway, I'm using different desktops for each context, with completely different pane layouts, network viewer settings, network snapping and other stuff. So I wish there was some way of forcing Houdini to automatically switch desktops, even if it involves some reasonable hacking (of
hou.pyperhaps?).If it's really impossible, then what I'd like to be able to do at least, is to create a radial menu with most used desktops, so that I could easily access them when necessary. But, I searched through HOM documentation (particularly the
hou.Desktopclass) and I didn't find any methods that would allow us to access saved desktops. So I'm not sure if that's possible either. Most probably not.
-
- vikus
- Member
- 247 posts
- Joined: May 2017
- Offline
Hi, you can try the following aproche:
- Create a shelftool, under edit tool > hotkeys set a hotkey for Network Pane
- Paste the following code in the script tabe:
With the network_type dictionary you can map network context to a desktop.
Use hotkey while under a network editor to change the mapped desktop.
Not sure if it is possible without pressing a key - there are some event handlers, but I didnt look closely.
Resources:
Is there a way to query the current context in Python? [forums.odforce.net]
hou.Desktop.setAsCurrent() [www.sidefx.com]
- Create a shelftool, under edit tool > hotkeys set a hotkey for Network Pane
- Paste the following code in the script tabe:
import hou desktop = hou.ui.curDesktop() pane = desktop.paneUnderCursor() network_editor = pane.currentTab() network_editor_type = network_editor.pwd().childTypeCategory() # network context mapping to desktops network_types: dict = {'Object' : 'Build', 'Sop' : 'Modeling', 'Vop' : 'Labs', 'Dop' : 'Technical', 'CopNet' : 'Image'} if (network_editor != None): for network_type, desktop_name in network_types.items(): if network_editor_type.name() == network_type: desktops_dict = dict((d.name(), d) for d in hou.ui.desktops()) desktops_dict[desktop_name].setAsCurrent() break
With the network_type dictionary you can map network context to a desktop.
Use hotkey while under a network editor to change the mapped desktop.
Not sure if it is possible without pressing a key - there are some event handlers, but I didnt look closely.
Resources:
Is there a way to query the current context in Python? [forums.odforce.net]
hou.Desktop.setAsCurrent() [www.sidefx.com]
Edited by vikus - Aug. 6, 2024 18:15:47
-
- ajz3d
- Member
- 654 posts
- Joined: Aug. 2014
- Offline
-
- vikus
- Member
- 247 posts
- Joined: May 2017
- Offline
I like the idea changing the desktop to match the network. In the last two days I jump from sops to lops all the time and don’t like to change the proper desktop manually as well. I use quickmarks and jump back and forth with it a lot - so for me it would already work to map the above function to the 1-5 keys.
I'll take a closer look at it over the next few days and let you know if it works.
ajz3dThere is for example the addEventLoopCallback [www.sidefx.com] which runs permanent once registered. But I dont think it is a good idea to compare always whether the current desktop matches the network context - but that should work. The best way would be to trigger a callback when you press something on the network, but the problem with that would be the query itself. Since if you trigger the function with a click, the network is probably still the same at that point, so you would need a post event or a delayed call.
If we could now use it as a callback function of desktop switching routines
I'll take a closer look at it over the next few days and let you know if it works.
-
- ajz3d
- Member
- 654 posts
- Joined: Aug. 2014
- Offline
viklcThat's a very good find!
There is for example the addEventLoopCallback which runs permanent once registered.

viklcNote that there are multiple ways of changing paths: mouse clicks over path bars, "U", "I" and "Enter" keys, Quickmarks, the Dashbox, from Python Shell and scripts, etc. So the implementation might become complicated very fast (if possible at all with the current function set). Maybe
The best way would be to trigger a callback when you press something on the network
addEventLoopCallback()is a good starting point after all? That is until we can figure out how to do it in a more optimal way, or after we place an RFE for required functions and our request is realized? I don't know.addEventLoopCallback()is called every ~50 ms. I'm not sure if it would bog down the UI, but I think it can be delayed with waitUntil(). One second seems reasonable to me.
-
- vikus
- Member
- 247 posts
- Joined: May 2017
- Offline
ajz3dThe parmanent query will certainly not affect Houdini, but it could cause a possible conflict an overlap with another function running in the background or something similar. So what we can try is to use one of the ui event reasons to first query if the user has pressed a key or mouse button and then ask if the current desktop matches the network context. But I'm not sure if the hou.uiEventReason [www.sidefx.com] works with the ui loop, I only used them with viewer states - this is probably the next step to find out.
addEventLoopCallback()is called every ~50 ms. I'm not sure if it would bog down the UI, but I think it can be delayed with waitUntil(). One second seems reasonable to me.
-
- vikus
- Member
- 247 posts
- Joined: May 2017
- Offline
So everything is needed is actually described here: Extending the network editor [www.sidefx.com].
The basic organization of the code is that all events are passed to the current context module (nodegraph.py by default)…
There is a function called handleEventCoroutine() that can be used to query whether the network editor has been changed or generally catch all network editor events.
Go to $HFS/houdini/pythonX.Ylibs/ and open nodegraph.py, search for handleEventCoroutine(), then look for the isinstance(uievent, ContextEvent) statement and paste the following code directly below it:
Like this:

Then save the file and restart houdini now it should work automatically.
The basic organization of the code is that all events are passed to the current context module (nodegraph.py by default)…
There is a function called handleEventCoroutine() that can be used to query whether the network editor has been changed or generally catch all network editor events.
Go to $HFS/houdini/pythonX.Ylibs/ and open nodegraph.py, search for handleEventCoroutine(), then look for the isinstance(uievent, ContextEvent) statement and paste the following code directly below it:
# network context mapping to desktops editor_desktop_map: dict = {'Object' : 'Build', 'Sop' : 'Modeling', 'Vop' : 'Labs', 'Dop' : 'Technical', 'CopNet' : 'Image'} current_editor_type = editor.pwd().childTypeCategory().name() desktop = hou.ui.curDesktop() if current_editor_type in editor_desktop_map.keys() and desktop.name() != editor_desktop_map[current_editor_type]: for editor_type, desktop_name in editor_desktop_map.items(): if current_editor_type == editor_type: desktops_dict = dict((d.name(), d) for d in hou.ui.desktops()) desktops_dict[desktop_name].setAsCurrent() break
Then save the file and restart houdini now it should work automatically.
-
- ajz3d
- Member
- 654 posts
- Joined: Aug. 2014
- Offline
Fabulous work! Well done, Viklc! 
Here's a patchfile that can be easily applied on a copy of
On GNU/Linux the patch can be applied with:
No idea how to do it on Windows.
Viklc, can you put your script on a git server?

Here's a patchfile that can be easily applied on a copy of
nodegraph.pyin order to avoid editing it manually. I modified the script slightly to put the dictionary into a separate module named deskassign.pyfor easier editing. It must be placed in the same path as patched nodegraph.py, which should be either:-
$HOUDINI_USER_PREF_DIR/python3.11libs, - or
$HOUDINI_PACKAGE_DIR/somepackage/python3.11libs, if one wants to use a package.
On GNU/Linux the patch can be applied with:
patch nodegraph.py < nodegraph.py.patch
Viklc, can you put your script on a git server?
Edited by ajz3d - Aug. 9, 2024 09:25:45
-
- vikus
- Member
- 247 posts
- Joined: May 2017
- Offline
Thanks, and thanks for providing useful ideas and pushing. 
You can find it now on Github as a package without modifying the original file. You can also use the generator wrapper to catch other editor events. Network-Context-Desktop-Mapping [github.com]

You can find it now on Github as a package without modifying the original file. You can also use the generator wrapper to catch other editor events. Network-Context-Desktop-Mapping [github.com]
-
- TristanG
- Member
- 6 posts
- Joined: Dec. 2021
- Offline
Greetings!
I've stumbled on this post and discover the script and package made by viklc and ajz3d. It works really well!
But I have one specific occurence when it doesn't work perfectly. It's when I switch from any context to LOP context. The desktop switches properly but the network goes back to /obj context or to the parent SOP level in case I dive inside a LOP Network. So I have to dive inside my /stage or LOP Network again.
I believe it's since Houdini 20 or 20.5 when switching to LOP, the current Desktop adapts to display Solaris and USD infos. Do you think this official behaviour could creates this conflict?
Thanks in advance!
I've stumbled on this post and discover the script and package made by viklc and ajz3d. It works really well!
But I have one specific occurence when it doesn't work perfectly. It's when I switch from any context to LOP context. The desktop switches properly but the network goes back to /obj context or to the parent SOP level in case I dive inside a LOP Network. So I have to dive inside my /stage or LOP Network again.
I believe it's since Houdini 20 or 20.5 when switching to LOP, the current Desktop adapts to display Solaris and USD infos. Do you think this official behaviour could creates this conflict?
Thanks in advance!
Edited by TristanG - Oct. 6, 2024 07:12:29
-
- ajz3d
- Member
- 654 posts
- Joined: Aug. 2014
- Offline
I think this behavior comes from the fact that desktops, apart from pane layout, also store pane paths (if applicable). So, whenever we load a desktop, we also load these paths and that's when Houdini may force us out from the context we are currently in, if it's unable to find those stored paths in the loaded scene.
Perhaps it can be fixed with some additional logic. For example, to first check what are the paths in currently opened panes, and reset them after desktop loads. But, it's somewhat problematic. For instance, if current desktop has two panes with two identical contexts (LOPs, for example), but different paths, and the loaded desktop has only one pane supporting paths, which path do we drop? Things like that. Also, we would still see a brief switch from one path to another. Each solution I can think of comes with its own share of drawbacks.
Perhaps it can be fixed with some additional logic. For example, to first check what are the paths in currently opened panes, and reset them after desktop loads. But, it's somewhat problematic. For instance, if current desktop has two panes with two identical contexts (LOPs, for example), but different paths, and the loaded desktop has only one pane supporting paths, which path do we drop? Things like that. Also, we would still see a brief switch from one path to another. Each solution I can think of comes with its own share of drawbacks.
-
- vikus
- Member
- 247 posts
- Joined: May 2017
- Offline
Hi TristanG,
I am glad you interested and hope it took not to long for the response. I also want you to know that I am working on a solution but have not had as much time in the last few weeks as there are some issues that need to be fixed.
Here some notes what is fixed and what has to be done:
At the moment the request for the desktop match is always triggered when something is changed in a network, so even if you change the desktop using the desktop dropdown menu, it can happen that you will drop to another desktop, as the network change event is also raised at this point. This is prevented by an additional query only under the mouse cursor, meaning that changes are only made if the user is currently under a network editor. This also solves the issue of multiple network change events depending on how many networks are currently present.
The other major issue is what ajz3d mentioned. So when you change the network context, the change event is fired, which will attempt to match the associated desktop, leaving the previous network where the change is made with the selected network context (network path); if you return to the previous desktop, the network is not matched.
There are two solutions for this:
I will implement some user options, such as only take effect when changing the root path, obj, img, mat, and so on. In addition also like dops which are subnets. Also interactive mapping and management direct in houdini.
I can't say how long it will take, some things have already been done, but the main issue still needs to be solved.
I am glad you interested and hope it took not to long for the response. I also want you to know that I am working on a solution but have not had as much time in the last few weeks as there are some issues that need to be fixed.
Here some notes what is fixed and what has to be done:
At the moment the request for the desktop match is always triggered when something is changed in a network, so even if you change the desktop using the desktop dropdown menu, it can happen that you will drop to another desktop, as the network change event is also raised at this point. This is prevented by an additional query only under the mouse cursor, meaning that changes are only made if the user is currently under a network editor. This also solves the issue of multiple network change events depending on how many networks are currently present.
The other major issue is what ajz3d mentioned. So when you change the network context, the change event is fired, which will attempt to match the associated desktop, leaving the previous network where the change is made with the selected network context (network path); if you return to the previous desktop, the network is not matched.
There are two solutions for this:
- before changing the desktop, reset the network path where the event is triggered, but this also triggers the network change event once again, which will lock the state. To solve this, we need to temporarily disable the event once before the reset.
- the other option is to keep track of the network desktop, which would make it possible to reset the network context afterwards, this would also avoid to trigger the event again as we are in the correct desktop. But keeping track of the networks is not so easy. Each pane has a unique session id, but under certain situations the id can be changed and the tracking gets lost. This sometimes happens when you manually load another desktop or add a new one. I can't say exactly when - so probaly I need to contact side fx.
I will implement some user options, such as only take effect when changing the root path, obj, img, mat, and so on. In addition also like dops which are subnets. Also interactive mapping and management direct in houdini.
I can't say how long it will take, some things have already been done, but the main issue still needs to be solved.
Edited by vikus - Oct. 19, 2024 13:50:54
-
- vikus
- Member
- 247 posts
- Joined: May 2017
- Offline
So finally got something usable. Tried many things, but nothing worked well. Ended upwith a retrictive approach that works stable and also takes care of paths. You can now switch from nodegraph path or subnets and the path will be taken over. It also works interactive you dont have to set anything in the external file by hand, simply using a hotkey under a nodegraph, which then maps its context to the current desktop - you can also delete the mapping directly, so everything works on the fly. Read the readme file on github.
nodegraphdesk [github.com]
And thanks again to you guys for pushing forward. Let me know any issues or improvements - enjoy.
nodegraphdesk [github.com]
And thanks again to you guys for pushing forward. Let me know any issues or improvements - enjoy.
Edited by vikus - Oct. 22, 2024 06:56:58
-
- TristanG
- Member
- 6 posts
- Joined: Dec. 2021
- Offline
-
- vikus
- Member
- 247 posts
- Joined: May 2017
- Offline
-
- ajz3d
- Member
- 654 posts
- Joined: Aug. 2014
- Offline
Great work, Viklc.
The script works like a charm, but unfortunately only for root contexts (
Do you think the program can be modified in such way that it also recognizes the type of nested networks, regardless of their location, or would it be too complicated?
The script works like a charm, but unfortunately only for root contexts (
/obj, /stage, /chop, etc.) For instance, it does not trigger if you dive into SOP context located in /obj/geo1or CHOPs nested in /obj/geo2/lopnet1/chopnet1. It treats them all as /obj.Do you think the program can be modified in such way that it also recognizes the type of nested networks, regardless of their location, or would it be too complicated?
-
- vikus
- Member
- 247 posts
- Joined: May 2017
- Offline
Hi nested networks works as well. Accept chops they dont trigger the network change event, cant say why, probably need to contact support - maybe an intersection with the coroutine.
I also have to notice that the mapping only works for the root path (context), so if you are in a nested network and try to map the context, the root (context) will be mapped. I will change this in the next update, also mapping for dops and so on.
I also have to notice that the mapping only works for the root path (context), so if you are in a nested network and try to map the context, the root (context) will be mapped. I will change this in the next update, also mapping for dops and so on.
Edited by vikus - Oct. 22, 2024 13:10:19
-
- vikus
- Member
- 247 posts
- Joined: May 2017
- Offline
Hm just tested with chops works as well, this was not the case before. So when you map context make sure you are in the root path of the network. The subnets will adopt this automatically. You can change the mapping for the subnets in configs subnetwork_context_map dictionary.
Edit:
Also make sure you are using the latest version, I did an update 1 hour ago where I removed the additional 'isUnderCursor()' query. That will also be the reason why chops didn't work as they are listed at top in the path dropdown menu, it's not in the nodegraph area to trigger the change event.
Edit:
Also make sure you are using the latest version, I did an update 1 hour ago where I removed the additional 'isUnderCursor()' query. That will also be the reason why chops didn't work as they are listed at top in the path dropdown menu, it's not in the nodegraph area to trigger the change event.
Edited by vikus - Oct. 22, 2024 13:36:59
-
- Quick Links



