Page MenuHome

Modal keymap customization from an addon is not restored properly
Closed, InvalidPublic

Authored By
Roger B (rboxman)
Jan 22 2019, 8:53 PM
Tokens
"Heartbreak" token, awarded by deadpin."Heartbreak" token, awarded by ckohl_art."Heartbreak" token, awarded by vitorbalbio."Like" token, awarded by maxivz."Burninate" token, awarded by zgorg."Like" token, awarded by bblanimation."Like" token, awarded by brilliant_ape."Like" token, awarded by aliasguru.

Description

System Information
Operating system: Win10
Graphics card: nVidia Quadro 600

Blender Version
Broken: 2.80 (sub 41), branch: master, commit date: 2019-01-22 16:54, hash: 25889423d324
Worked: unsure

Short description of error
It seems that if an addon makes a customization to a modal keymap, this customization only works until you restart blender. After restart, the keymap is not restored properly (left blank) and the only way to fix is to disable/re-enable the addon again.

Exact steps for others to reproduce the error

  • Install and Enable the attached .py addon
    • It adds a modal keymap for circle select (makes it so that circle select is active only if you hold down the C key)
  • Save Preferences
  • Notice that things work correctly. Circle select is only active while holding down the C key
  • Restart blender
  • Notice the keymap no longer works. Check the keymap in user preferences and notice that the new entry is actually blanked out

Event Timeline

The same issue happens when you define a complete new tool with a shortcut using bl_keymap. On first Add-on activation, the shortcut works. On restarting Blender, it is non-functional. But if you reload all scripts while Blender is still running, the shortcut works again. I have used this class from the Templates to verify this behavior:

bl_info = {
    "name": "Shortcutter",
    "author": "Bug Reporter",
    "version": (1, 0),
    "blender": (2, 80, 0),
}

import bpy
from bpy.types import WorkSpaceTool

class MyTool(WorkSpaceTool):
    bl_space_type='VIEW_3D'
    bl_context_mode='OBJECT'

    # The prefix of the idname should be your add-on name.
    bl_idname = "my_template.my_circle_select"
    bl_label = "My Circle Select"
    bl_description = (
        "This is a tooltip\n"
        "with multiple lines"
    )
    bl_icon = "ops.generic.select_circle"
    bl_widget = None
    bl_keymap = (
        ("view3d.select_circle", {"type": 'LEFTMOUSE', "value": 'PRESS'},
         {"properties": [("wait_for_input", False)]}),
        ("view3d.select_circle", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
         {"properties": [("mode", 'SUB'), ("wait_for_input", False)]}),
    )

    def draw_settings(context, layout, tool):
        props = tool.operator_properties("view3d.select_circle")
        layout.prop(props, "mode")
        layout.prop(props, "radius")


def register():
    bpy.utils.register_tool(MyTool, after={"builtin.scale_cage"}, separator=True, group=True)

def unregister():
    bpy.utils.unregister_tool(MyTool)

if __name__ == "__main__":
    register()

Is this something that's on the ToDo list for 2.81 already? Or is there a workaround for it? Not being able to have modifier keys for custom tools limits the use quite a bit.

when will solve this problem? I can't advance because of it in my development

Hi @Max Derksen (Derksen) , if you are looking for a workaound for the problem of custom tools not working on Blender restart, you will find it in addons/mesh_snap_utilities_line/__init__.py
A simplified version of it is in: https://raw.githubusercontent.com/Shriinivas/blenderbezierutils/master/blenderbezierutils.py
(Essentially, you would need to register the tool and keymap in some roundabout way)

@Shrinivas (Shrinivas) (Shrinivas) , thanks, I'll try this for the instrument. What about saving the shortcuts in the settings addon? that doesn't work either

@Max Derksen (Derksen) Maybe there is also an option for saving the shortcuts in the workaround. Just check keys.py in snap utilities.
I am an add-on developer and faced the same issue in my tool. I got the pointer about this workaround from one of the users (thanks @yoshiki nosaka (sakana3)).

-- (zgorg) added a subscriber: -- (zgorg).EditedOct 23 2019, 5:16 PM

I think this is a high priority subject around keys save and more clear information about this
I tried to modify a key and at the same add another one. I had to change addon_keymaps to user_keymaps = [] but I could not register the other shortcut at the same time so I put user_keymaps in the settings too and I get back and all the default keys in mesh of all maps were erased. I had a save. but doing this because my shortcut was never registred. I see kmi.active=True on old scripts but I never found an explanation. some people use timers other handlers and I saw an update on a property from addon pref. why to go there? well I'm still a noob but it's not possible to improve this to be more easy to use? I think this is a priority as the fact to have new keys in new versions added to own keys config. I don't show the answer of Brecht about this again...I saw a script to find duplicates that's a good begining

I have a key reappearing even when the addon is totally uninstall. I even purge py cache (to see if any effect). It should be a problem in user.pref. but really I don't get it and still reading more infos. I found this https://blenderartists.org/t/key-config-confusion/637985/4 the last comment. it is maybe a little hard, and maybe he didn't understand how it's working. but please provide more clear info about all this. I can disable the key but not erase it. and it's getting back when I uninstall another addon with the same class in. so I changed the name class. no effect.
I found the actual help was in 2.73 and maybe before. this is a good example but plz do more that put 2.8 in the BL at first. I watch several "multi" addons and they are all reporting some issues about this. so with my little beginner level it's just a pita

Philipp Oeser (lichtwerk) raised the priority of this task from 50 to High.Nov 6 2019, 7:25 PM

This looks like it could use some attention? (will dare setting to High prio...)

I think problem hidden here

\blender-2.82-e5b788bad8bc-windows64\2.82\scripts\modules\bpy\utils\__init__.py
# Convert the class into a ToolDef.
def tool_from_class(tool_cls):
    # Convert class to tuple, store in the class for removal.
    tool_def = ToolDef.from_dict({
        "idname": tool_cls.bl_idname,
        "label": tool_cls.bl_label,
        "description": getattr(tool_cls, "bl_description", tool_cls.__doc__),
        "icon": getattr(tool_cls, "bl_icon", None),
        "cursor": getattr(tool_cls, "bl_cursor", None),
        "widget": getattr(tool_cls, "bl_widget", None),
        "keymap": getattr(tool_cls, "bl_keymap", None),
        "data_block": getattr(tool_cls, "bl_data_block", None),
        "operator": getattr(tool_cls, "bl_operator", None),
        "draw_settings": getattr(tool_cls, "draw_settings", None),
        "draw_cursor": getattr(tool_cls, "draw_cursor", None),
    })
    tool_cls._bl_tool = tool_def

    keymap_data = tool_def.keymap
    if keymap_data is not None:
        if context_mode is None:
            context_descr = "All"
        else:
            context_descr = context_mode.replace("_", " ").title()
        from bpy import context
        wm = context.window_manager
        kc = wm.keyconfigs.default  #  <-------------------------<-----------------------< HERE
        if callable(keymap_data[0]):
            cls._km_action_simple(kc, context_descr, tool_def.label, keymap_data)
    return tool_def

I've tested it with kc = wm.keyconfigs.user, everything work's well.
API: keyconfigs.default
API: keyconfigs.user

If it's so, then one line in function unregister_tool (scripts\modules\bpy\utils\__init__.py) should be changed same way from

kc = wm.keyconfigs.default

to

kc = wm.keyconfigs.user

otherwise addon will throw error when you deactivate it

@Cirno (Cirno)
All good for now, thanks for quick workaround

Tested the fix provided by @Cirno (Cirno) and can confirm this works! Attatching a diff for merging in case one of the devs wants to use it.

I want to bump this, since fix seems to be really so simple (one line of code). @Campbell Barton (campbellbarton)

Campbell Barton (campbellbarton) changed the task status from Confirmed to Needs Information from User.EditedMar 26 2020, 6:32 AM
Campbell Barton (campbellbarton) lowered the priority of this task from High to Normal.
Campbell Barton (campbellbarton) changed the subtype of this task from "Bug" to "Report".

As far as I can see this is working as expected.

  • The default key-map is not saved in preferences, this is used unless customizations have been made.
  • The preferences key-map is saved, this is only for the user to edit via the key-map editor.

So it's correct for the tool to load a keymap to the 'default' keymap, allowing the user to overlay changes to this in the 'user' keymap.

If registering tools writes into the user keymap, there is no way for users to make changes ontop of the default.


Keeping this open in case there is a use-case I'm missing here. Otherwise I think this can be closed.

Most likely this is something that should be documented in more detail.

Hmm, I'm not sure I follow completely. How would you implement the issue described in the original part of the report where I want to enable circle select only while I'm holding down the C key. Or are you saying that such a thing cannot be done within an addon?

This works in my script that's attached but only until I restart blender. Once I restart it looks like my saved keymap has been overwritten and I have to manually reload the addon for it to be brought back.

I can reproduce this by adding a bl_info dictionary to the Ui Tool Simple template and registering it as an addon as @Rainer Trummer (aliasguru) pointed out.

The next time i start blender and activate the tool i get following error in the console:
WARN (wm.keymap): /home/david/blender-git/blender/source/blender/windowmanager/intern/wm_keymap.c:469 WM_keymap_poll: empty keymap '3D View Tool: Object, My Circle Select'

After running the "Reload Scripts" operator that error won't show up and the tool works as expected again.

If so, "bl_keymap" should be removed from WorkSpaceTool.
A setting that disappears on reboot makes no sense and will only mislead add-on developers.

Committed rBe8dd96516c60: Keymap: disallow modal key-maps in add-ons keyconfig with disallows extending modal keymaps as it's not the intended use of add-on keymaps - which is to allow adding short-cuts which call operators defined by the add-ons.

Using add-on keymaps to customize existing modal key-maps basically worked in some cases by accident.

Disabling this as it's a customization which can be made by the keymap editor.

@yoshiki nosaka (sakana3), issues with WorkSpaceTool keymaps should be reported separately since it's not related to modal keymaps.

Jesse Y (deadpin) awarded a token.

@Campbell Barton (campbellbarton)
The Issue described in T66655 (which was merged with this Task) still persist. Looks like it is a separate issue and should be reopened.

Re-opening tasks that were closed as duplicate, I'll look into those since they aren't related to modal key-maps.