Preferences: Keymap Preferences not visible afert importing custom key map #65121

Closed
opened 2019-05-25 16:49:12 +02:00 by Michael P. · 43 comments

System Information
Operating system: Windows-7-6.1.7601-SP1 64 Bits
Graphics card: GeForce GTX 760/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 390.65

Blender Version
Broken: version: 2.80 (sub 72), branch: blender2.7, commit date: 2019-05-24 22:21, hash: caf52e3779
Worked: (optional)

Short description of error
Preferences: Keymap Preferences not visible afert importing custom key map

Exact steps for others to reproduce the error

Found this after I saved and imported my key map and then wanted to adjust mouse select button.

  • Open Blender
  • Go to Preferences > Keymap
  • Click Export Button
  • Import the exported File
  • Go to Preferences > Keymap
  • The Panel Preferences can't be seen

2019-05-25-custom-keymap-no-preferences-1.png
This is what I get.

2019-05-25-custom-keymap-no-preferences-2.png
This is what I get when I select the blender key map.

**System Information** Operating system: Windows-7-6.1.7601-SP1 64 Bits Graphics card: GeForce GTX 760/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 390.65 **Blender Version** Broken: version: 2.80 (sub 72), branch: blender2.7, commit date: 2019-05-24 22:21, hash: `caf52e3779` Worked: (optional) **Short description of error** Preferences: Keymap Preferences not visible afert importing custom key map **Exact steps for others to reproduce the error** Found this after I saved and imported my key map and then wanted to adjust mouse select button. - Open Blender - Go to Preferences > Keymap - Click Export Button - Import the exported File - Go to Preferences > Keymap - The Panel Preferences can't be seen ![2019-05-25-custom-keymap-no-preferences-1.png](https://archive.blender.org/developer/F7068113/2019-05-25-custom-keymap-no-preferences-1.png) This is what I get. ![2019-05-25-custom-keymap-no-preferences-2.png](https://archive.blender.org/developer/F7068115/2019-05-25-custom-keymap-no-preferences-2.png) This is what I get when I select the blender key map.
Author

Added subscriber: @MichaelParucha

Added subscriber: @MichaelParucha

#91860 was marked as duplicate of this issue

#91860 was marked as duplicate of this issue

#76028 was marked as duplicate of this issue

#76028 was marked as duplicate of this issue

#75624 was marked as duplicate of this issue

#75624 was marked as duplicate of this issue

#74132 was marked as duplicate of this issue

#74132 was marked as duplicate of this issue

#73872 was marked as duplicate of this issue

#73872 was marked as duplicate of this issue

Added subscriber: @brecht

Added subscriber: @brecht

Changed status from 'Open' to: 'Archived'

Changed status from 'Open' to: 'Archived'
Brecht Van Lommel self-assigned this 2019-05-25 20:52:18 +02:00

This is by design, these preferences are only available for the default keymap. They can't be automatically applied to any keymap.

This is by design, these preferences are only available for the default keymap. They can't be automatically applied to any keymap.
Author

@brecht This means that when set those are exported too? Or how can they be changed then in the saved custom settings if needed?

@brecht This means that when set those are exported too? Or how can they be changed then in the saved custom settings if needed?

Yes, the preferences are baked into the exported keymap.

Yes, the preferences are baked into the exported keymap.
Author

Hmm, if I change the default "Select With" to right and export the key map its empty. So where are thos settings?

grafik.png

grafik.png

test-export.py

Hmm, if I change the default "Select With" to right and export the key map its empty. So where are thos settings? ![grafik.png](https://archive.blender.org/developer/F7068436/grafik.png) ![grafik.png](https://archive.blender.org/developer/F7068441/grafik.png) [test-export.py](https://archive.blender.org/developer/F7068443/test-export.py)
Author

Added subscribers: @WilliamReynish, @ideasman42

Added subscribers: @WilliamReynish, @ideasman42
Author

@brecht One of the use cases for exporting the key map would be to install it on a second pc. So to do that I need to set the preferences in the Blender key map and save them and then import the custom key map, correct?

@WilliamReynish, @ideasman42

@brecht One of the use cases for exporting the key map would be to install it on a second pc. So to do that I need to set the preferences in the Blender key map and save them and then import the custom key map, correct? @WilliamReynish, @ideasman42

Changed status from 'Archived' to: 'Open'

Changed status from 'Archived' to: 'Open'

That does seem like a bug. If you export with all keymaps the changes should be included.

In general for sharing preferences between computers it's more reliable to share a userpref.blend, the way keymap import/export works now is really geared towards fully custom keymaps, not so much a few smaller tweaks.

That does seem like a bug. If you export with all keymaps the changes should be included. In general for sharing preferences between computers it's more reliable to share a userpref.blend, the way keymap import/export works now is really geared towards fully custom keymaps, not so much a few smaller tweaks.

Added subscriber: @zgorg

Added subscriber: @zgorg

thks for the answer. very high priority for me. because of add-ons for instance. I did a ctrl tab under my own settings and was not working under 2.8 keymap. then I remember this problem of default interface on 2.8 not appearing on other keymaps. imagine a non confirmed user dealing with this. a nightmare. more when adding new keys in 2.8 like new outliner shortcuts they are not added to other shortcut keypmaps. imagine the deal to check every new changes by hand. example in text editor the new add comment toggle. this is an absolute priority in fact when dealing with millions of users and 2.8 shortcuts are far to be logical even for new users. but this is my own opinion

thks for the answer. very high priority for me. because of add-ons for instance. I did a ctrl tab under my own settings and was not working under 2.8 keymap. then I remember this problem of default interface on 2.8 not appearing on other keymaps. imagine a non confirmed user dealing with this. a nightmare. more when adding new keys in 2.8 like new outliner shortcuts they are not added to other shortcut keypmaps. imagine the deal to check every new changes by hand. example in text editor the new add comment toggle. this is an absolute priority in fact when dealing with millions of users and 2.8 shortcuts are far to be logical even for new users. but this is my own opinion
  • "One of the use cases for exporting the key map would be to install it on a second pc. So to do that I need to set the preferences in the Blender key map and save them and then import the custom key map, correct?"
  • "In general for sharing preferences between computers it's more reliable to share a userpref.blend"

for information if keymaps are changed in Blender saving preferences won't save the previous state for your keys. like I'm explaining it there and the answer sound well there is no way to record your own keys.  #70436 New shortcuts not added to my personal shortcut profile - Mozilla Firefox_2.jpg

- "One of the use cases for exporting the key map would be to install it on a second pc. So to do that I need to set the preferences in the Blender key map and save them and then import the custom key map, correct?" - "In general for sharing preferences between computers it's more reliable to share a userpref.blend" for information if keymaps are changed in Blender saving preferences won't save the previous state for your keys. like I'm explaining it there and the answer sound well there is no way to record your own keys. ![ #70436 New shortcuts not added to my personal shortcut profile - Mozilla Firefox_2.jpg](https://archive.blender.org/developer/F7791491/_T70436_New_shortcuts_not_added_to_my_personal_shortcut_profile_-_Mozilla_Firefox_2.jpg)
Brecht Van Lommel was unassigned by Dalai Felinto 2019-12-23 16:34:17 +01:00

Changed status from 'Confirmed' to: 'Archived'

Changed status from 'Confirmed' to: 'Archived'
Campbell Barton self-assigned this 2020-02-03 05:03:57 +01:00

Closing as this is working as intended.

Supporting preferences on saved keymaps is a non-trivial task.

Closing as this is working as intended. Supporting preferences on saved keymaps is a non-trivial task.

Added subscribers: @RUben, @jenkm

Added subscribers: @RUben, @jenkm

Added subscriber: @borschberry

Added subscriber: @borschberry

For example, I have a very complicated set of hotkeys that I transfer from version to version. Now, do I need to transfer it manually?
It seems to me that new hotkeys should be assigned default values, they should not disappear.

It's just a shame guys. Close the bug report because the bug is difficult to fix?

For example, I have a very complicated set of hotkeys that I transfer from version to version. Now, do I need to transfer it manually? It seems to me that new hotkeys should be assigned default values, they should not disappear. It's just a shame guys. Close the bug report because the bug is difficult to fix?

Added subscriber: @DanielGrauer

Added subscriber: @DanielGrauer

Added subscriber: @RomboutVersluijs

Added subscriber: @RomboutVersluijs

I wonder why this preferences isnt added, i read this is by design. But if one uses a keymap and uses that same keymap on a different system. He can never change the preferences part which shows at the top.

As a test i tried adding back that preferences part in a custom keymap and it works fine then. Atleasy i thought, i noticed that i missed the load function. I come back to that in last part here after editing it a bit more

The things like orbit and right- or left-click select are not shown anymore and cant not be saved, as far as i know the keymap. I still believe this is a bug, because a keymap doesnt behave the same. Now its set is set and you can never change it again, that doesnt feel right. The issue now is once you have a keymap setup, you can never change it again. Unless you run a find/replace in that py file ofcourse. Im not sure much users will come to that idea though. Wouldnt it be better to separate that main part into its own small operator. So it will always be visible and thus custom hotkeys can always be adjusted concerning the main navigation items.

Screen Shot 2020-03-19 at 15.54.28.png

EDIT
I did a test by adjust IO.py took me a while to get it working and i did need to hardcode blender app path. But now each preset i save can still be adjusted after wards. I basically keep that preferences part and loads the blender_default.py
So far my tests didnt show issues. The only thing though on initial load, it shows LEFT click for selection since that is the default in the blender.py file. I could make find the first mouse click in the shortcuts and use that as default.

io.py

Screen Shot 2020-03-19 at 16.01.17.png

I wonder why this preferences isnt added, i read this is by design. But if one uses a keymap and uses that same keymap on a different system. He can never change the preferences part which shows at the top. As a test i tried adding back that preferences part in a custom keymap and it works fine then. Atleasy i thought, i noticed that i missed the load function. I come back to that in last part here after editing it a bit more The things like orbit and right- or left-click select are not shown anymore and cant not be saved, as far as i know the keymap. I still believe this is a bug, because a keymap doesnt behave the same. Now its set is set and you can never change it again, that doesnt feel right. The issue now is once you have a keymap setup, you can never change it again. Unless you run a find/replace in that py file ofcourse. Im not sure much users will come to that idea though. Wouldnt it be better to separate that main part into its own small operator. So it will always be visible and thus custom hotkeys can always be adjusted concerning the main navigation items. ![Screen Shot 2020-03-19 at 15.54.28.png](https://archive.blender.org/developer/F8416389/Screen_Shot_2020-03-19_at_15.54.28.png) EDIT I did a test by adjust IO.py took me a while to get it working and i did need to hardcode blender app path. But now each preset i save can still be adjusted after wards. I basically keep that preferences part and loads the blender_default.py So far my tests didnt show issues. The only thing though on initial load, it shows LEFT click for selection since that is the default in the blender.py file. I could make find the first mouse click in the shortcuts and use that as default. [io.py](https://archive.blender.org/developer/F8416558/io.py) ![Screen Shot 2020-03-19 at 16.01.17.png](https://archive.blender.org/developer/F8416387/Screen_Shot_2020-03-19_at_16.01.17.png)
Member

closed because its a non trivial task? please explain how that solves the issue

closed because its a non trivial task? please explain how that solves the issue

It doesn't solve the issue, but it means it's not considered a bug and should not be in our bug tracker, it's a feature request.

It doesn't solve the issue, but it means it's not considered a bug and should not be in our bug tracker, it's a feature request.

@RomboutVersluijs, you might be able to make those buttons appear, but I doubt they actually work?

@RomboutVersluijs, you might be able to make those buttons appear, but I doubt they actually work?

I tried it and it does work. Though i believe i need to run them again to make them actually change all buttons. Ive tried adding the add set up so they are read when keymap is read back in and don't reset to defaults. I find my method works better then current behavior because i cant change anything. Now i can change it afterward :)

The only thing which I'm still working on is making a custom blender_default.py because currently my io.py gets all defaults as well. It should only take the changed ones, I'm not 100% sure of that though. But the thing is if you change the keymap, then all keys need to be changed i believe. So perhaps my setup is the proper method after all. The keymap get twice as big now because it contains 16k of line in shortcuts ... oopss But i am able to keep switching now and don't need to start all over again. This is how it currently works, once you've set those preferences at the top, there is no way (like a normal way) to change it again.

PS can i as how i can reach the default preset folder within the app on OSX? Now I've hardcoded the path but i want to share it, it will not work. See #157 & #158

Ive added my change io.py file with how i add bak those key inputs in a keymap file
io.py

I tried it and it does work. Though i believe i need to run them again to make them actually change all buttons. Ive tried adding the add set up so they are read when keymap is read back in and don't reset to defaults. I find my method works better then current behavior because i cant change anything. Now i can change it afterward :) The only thing which I'm still working on is making a custom blender_default.py because currently my io.py gets all defaults as well. It should only take the changed ones, I'm not 100% sure of that though. But the thing is if you change the keymap, then all keys need to be changed i believe. So perhaps my setup is the proper method after all. The keymap get twice as big now because it contains 16k of line in shortcuts ... oopss But i am able to keep switching now and don't need to start all over again. This is how it currently works, once you've set those preferences at the top, there is no way (like a normal way) to change it again. PS can i as how i can reach the default preset folder within the app on OSX? Now I've hardcoded the path but i want to share it, it will not work. See #157 & #158 Ive added my change io.py file with how i add bak those key inputs in a keymap file [io.py](https://archive.blender.org/developer/F8435674/io.py)

Added subscribers: @roberto.loriga, @TheRedWaxPolice

Added subscribers: @roberto.loriga, @TheRedWaxPolice

Removed subscriber: @jenkm

Removed subscriber: @jenkm

Added subscriber: @JoelArt

Added subscriber: @JoelArt

In #65121#894819, @RomboutVersluijs wrote:
I wonder why this preferences isnt added, i read this is by design. But if one uses a keymap and uses that same keymap on a different system. He can never change the preferences part which shows at the top.

As a test i tried adding back that preferences part in a custom keymap and it works fine then. Atleasy i thought, i noticed that i missed the load function. I come back to that in last part here after editing it a bit more

The things like orbit and right- or left-click select are not shown anymore and cant not be saved, as far as i know the keymap. I still believe this is a bug, because a keymap doesnt behave the same. Now its set is set and you can never change it again, that doesnt feel right. The issue now is once you have a keymap setup, you can never change it again. Unless you run a find/replace in that py file ofcourse. Im not sure much users will come to that idea though. Wouldnt it be better to separate that main part into its own small operator. So it will always be visible and thus custom hotkeys can always be adjusted concerning the main navigation items.

Screen Shot 2020-03-19 at 15.54.28.png

EDIT
I did a test by adjust IO.py took me a while to get it working and i did need to hardcode blender app path. But now each preset i save can still be adjusted after wards. I basically keep that preferences part and loads the blender_default.py
So far my tests didnt show issues. The only thing though on initial load, it shows LEFT click for selection since that is the default in the blender.py file. I could make find the first mouse click in the shortcuts and use that as default.

io.py

Screen Shot 2020-03-19 at 16.01.17.png

How do I use the io.py script?

BTW, I've suffered a lot due to this IDIOTIC design, how can the prefs not be available for all keymaps. If you've set left click as default then you are stuck with it for ever on your new keymap. How do I even make backups of my default keymap without losing the preferences when loading them back in again.

> In #65121#894819, @RomboutVersluijs wrote: > I wonder why this preferences isnt added, i read this is by design. But if one uses a keymap and uses that same keymap on a different system. He can never change the preferences part which shows at the top. > > As a test i tried adding back that preferences part in a custom keymap and it works fine then. Atleasy i thought, i noticed that i missed the load function. I come back to that in last part here after editing it a bit more > > The things like orbit and right- or left-click select are not shown anymore and cant not be saved, as far as i know the keymap. I still believe this is a bug, because a keymap doesnt behave the same. Now its set is set and you can never change it again, that doesnt feel right. The issue now is once you have a keymap setup, you can never change it again. Unless you run a find/replace in that py file ofcourse. Im not sure much users will come to that idea though. Wouldnt it be better to separate that main part into its own small operator. So it will always be visible and thus custom hotkeys can always be adjusted concerning the main navigation items. > > ![Screen Shot 2020-03-19 at 15.54.28.png](https://archive.blender.org/developer/F8416389/Screen_Shot_2020-03-19_at_15.54.28.png) > > EDIT > I did a test by adjust IO.py took me a while to get it working and i did need to hardcode blender app path. But now each preset i save can still be adjusted after wards. I basically keep that preferences part and loads the blender_default.py > So far my tests didnt show issues. The only thing though on initial load, it shows LEFT click for selection since that is the default in the blender.py file. I could make find the first mouse click in the shortcuts and use that as default. > > [io.py](https://archive.blender.org/developer/F8416558/io.py) > > > ![Screen Shot 2020-03-19 at 16.01.17.png](https://archive.blender.org/developer/F8416387/Screen_Shot_2020-03-19_at_16.01.17.png) How do I use the io.py script? BTW, I've suffered a lot due to this IDIOTIC design, how can the prefs not be available for all keymaps. If you've set left click as default then you are stuck with it for ever on your new keymap. How do I even make backups of my default keymap without losing the preferences when loading them back in again.

@JoelArt

Hi Joel, i havent tested it yet in newer versions though. I replace the file located in this folder

Fill XX with personal and bl version

C:\Program Files\Blender Foundation\Blender XXX\XXX\scripts\modules\bl_keymap_utils

Be sure to either move that old file or rename it just in case it does break something also test it properly. I ran it a couple times and didnt see weird behavior, though i didnt check all shortcuts ofcourse. I randomly tried as many as i could and they seemed to work. I also check one of the old keymaps stored in the user-folder.

Fill XX with personal and bl version

C:\Users\XXXXXX\AppData\Roaming\Blender Foundation\Blender\XXX\scripts\presets\keyconfig

You could also try opening one of the personal keymaps in a code-editor which allows you to compare them. Then see if they are different, you would do this by first saving a keymap without this new io.py, so save say "keymap-A" then replace (keep the old one!!!!) the io.py and name this "keymap-B" then compared them. The new version should have added code which i show below with the lien numbers.
I just check the io.py in 2.91 and they have added some lines to io.py, it now sorts the keymaps when storing, allows for easier comparing.

Another method is by adding the top part in case you want to edit it, but you would need to do that every time, then reload Blender. I think this is to tedious to do, the thing is each time you press something in the at top part, it loads and adjust all shortcuts on the fly. I cant remember how i did that part. I just looked at their base preset and it would take quite some time for me to figure it out again.

What you would need to is is copy/paste # 157, the part which says ''fw("import os\n.....``` and then lots code between the double quotation marks. You also need to add #206 to #231 and replace that with #212.
I added the adjusted version here below, i wasnt sure you would be able to do it yourself.

Again, make a backup or rename that io.py before you do this, otherwise you could break the ability to properly save keymaps in the future

- ##### BEGIN GPL LICENSE BLOCK #####
#
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
#
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- GNU General Public License for more details.
#
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

# <pep8 compliant>

- -----------------------------------------------------------------------------
- Export Functions

__all__ = (
    "keyconfig_export_as_data",
    "keyconfig_import_from_data",
    "keyconfig_init_from_data",
    "keyconfig_merge",
    "keymap_init_from_data",
)


def indent(levels):
    return levels * " "


def round_float_32(f):
    from struct import pack, unpack
    return unpack("f", pack("f", f))[0]


def repr_f32(f):
    f_round = round_float_32(f)
    f_str = repr(f)
    f_str_frac = f_str.partition(".")[2]
    if not f_str_frac:
        return f_str
    for i in range(1, len(f_str_frac)):
        f_test = round(f, i)
        f_test_round = round_float_32(f_test)
        if f_test_round == f_round:
            return "%.*f" % (i, f_test)
    return f_str


def kmi_args_as_data(kmi):
    s = [
        f"\"type\": '{kmi.type}'",
        f"\"value\": '{kmi.value}'"
    ]

    if kmi.any:
        s.append("\"any\": True")
    else:
        if kmi.shift:
            s.append("\"shift\": True")
        if kmi.ctrl:
            s.append("\"ctrl\": True")
        if kmi.alt:
            s.append("\"alt\": True")
        if kmi.oskey:
            s.append("\"oskey\": True")
    if kmi.key_modifier and kmi.key_modifier != 'NONE':
        s.append(f"\"key_modifier\": '{kmi.key_modifier}'")

    return "{" + ", ".join(s) + "}"


def _kmi_properties_to_lines_recursive(level, properties, lines):
    from bpy.types import OperatorProperties

    def string_value(value):
        if isinstance(value, (str, bool, int, set)):
            return repr(value)
        elif isinstance(value, float):
            return repr_f32(value)
        elif getattr(value, '__len__', False):
            return repr(tuple(value))
        raise Exception(f"Export key configuration: can't write {value!r}")

    for pname in properties.bl_rna.properties.keys():
        if pname != "rna_type":
            value = getattr(properties, pname)
            if isinstance(value, OperatorProperties):
                lines_test = []
                _kmi_properties_to_lines_recursive(level + 2, value, lines_test)
                if lines_test:
                    lines.append(f"(")
                    lines.append(f"\"{pname}\",\n")
                    lines.append(f"{indent(level + 3)}" "[")
                    lines.extend(lines_test)
                    lines.append("],\n")
                    lines.append(f"{indent(level + 3)}" "),\n" f"{indent(level + 2)}")
                del lines_test
            elif properties.is_property_set(pname):
                value = string_value(value)
                lines.append((f"(\"{pname}\", {value:s}),\n" f"{indent(level + 2)}"))


def _kmi_properties_to_lines(level, kmi_props, lines):
    if kmi_props is None:
        return

    lines_test = [f"\"properties\":\n" f"{indent(level + 1)}" "["]
    _kmi_properties_to_lines_recursive(level, kmi_props, lines_test)
    if len(lines_test) > 1:
        lines_test.append("],\n")
        lines.extend(lines_test)


def _kmi_attrs_or_none(level, kmi):
    lines = []
    _kmi_properties_to_lines(level + 1, kmi.properties, lines)
    if kmi.active is False:
        lines.append(f"{indent(level)}\"active\":" "False,\n")
    if not lines:
        return None
    return "".join(lines)


def keyconfig_export_as_data(wm, kc, filepath, *, all_keymaps=False):
    # Alternate format

    - Generate a list of keymaps to export:
    #
    - First add all user_modified keymaps (found in keyconfigs.user.keymaps list),
    - then add all remaining keymaps from the currently active custom keyconfig.
    #
    - Sort the resulting list according to top context name,
    - while this isn't essential, it makes comparing keymaps simpler.
    #
    - This will create a final list of keymaps that can be used as a "diff" against
    - the default blender keyconfig, recreating the current setup from a fresh blender
    # without needing to export keymaps which haven't been edited.

    class FakeKeyConfig:
        keymaps = []
    edited_kc = FakeKeyConfig()
    for km in wm.keyconfigs.user.keymaps:
        if all_keymaps or km.is_user_modified:
            edited_kc.keymaps.append(km)
    # merge edited keymaps with non-default keyconfig, if it exists
    if kc != wm.keyconfigs.default:
        export_keymaps = keyconfig_merge(edited_kc, kc)
    else:
        export_keymaps = keyconfig_merge(edited_kc, edited_kc)

    - Sort the keymap list by top context name before exporting,
    - not essential, just convenient to order them predictably.
    export_keymaps.sort(key=lambda k: k[0].name)

    with open(filepath, "w", encoding="utf-8") as fh:
        fw = fh.write
        fw("keyconfig_data = \\\n[")
        
                fw("import os\nimport bpy\nfrom bpy.props import (\n    BoolProperty,\n    EnumProperty,\n)\n\nDIRNAME, FILENAME = os.path.split(__file__)\nIDNAME = os.path.splitext(FILENAME)[0]\n\ndef update_fn(_self, _context):\n    load()\n\n\nclass Prefs(bpy.types.KeyConfigPreferences):\n    bl_idname = IDNAME\n\n    select_mouse: EnumProperty(\n        name=\"Select Mouse\",\n        items=(\n            (\'LEFT\', \"Left\",\n             \"Use left mouse button for selection. \"\n             \"The standard behavior that works well for mouse, trackpad and tablet devices\"),\n            (\'RIGHT\', \"Right\",\n             \"Use right mouse button for selection, and left mouse button for actions. \"\n             \"This works well primarily for keyboard and mouse devices\"),\n        ),\n        description=(\n            \"Mouse button used for selection\"\n        ),\n        update=update_fn,\n    )\n    spacebar_action: EnumProperty(\n        name=\"Spacebar Action\",\n        items=(\n            (\'PLAY\', \"Play\",\n             \"Toggle animation playback \"\n             \"(\'Shift-Space\' for Tools)\",\n             1),\n            (\'TOOL\', \"Tools\",\n             \"Open the popup tool-bar\\n\"\n             \"When \'Space\' is held and used as a modifier:\\n\"\n             \"\u2022 Pressing the tools binding key switches to it immediately.\\n\"\n             \"\u2022 Dragging the cursor over a tool and releasing activates it (like a pie menu).\\n\"\n             \"For Play use \'Shift-Space\'\",\n             0),\n            (\'SEARCH\', \"Search\",\n             \"Open the operator search popup\",\n             2),\n        ),\n        description=(\n            \"Action when \'Space\' is pressed\"\n        ),\n        default=\'PLAY\',\n        update=update_fn,\n    )\n    use_select_all_toggle: BoolProperty(\n        name=\"Select All Toggles\",\n        description=(\n            \"Causes select-all (\'A\' key) to de-select in the case a selection exists\"\n        ),\n        default=False,\n        update=update_fn,\n    )\n\n    gizmo_action: EnumProperty(\n        name=\"Activate Gizmo\",\n        items=(\n            (\'PRESS\', \"Press\", \"Press causes immediate activation, preventing click being passed to the tool\"),\n            (\'DRAG\', \"Drag\", \"Drag allows click events to pass through to the tool, adding a small delay\"),\n        ),\n        description=\"Activation event for gizmos that support drag motion\",\n        default=\'DRAG\',\n        update=update_fn,\n    )\n\n    # 3D View\n    use_v3d_tab_menu: BoolProperty(\n        name=\"Tab for Pie Menu\",\n        description=(\n            \"Causes tab to open pie menu (swaps \'Tab\' / \'Ctrl-Tab\')\"\n        ),\n        default=False,\n        update=update_fn,\n    )\n    use_v3d_shade_ex_pie: BoolProperty(\n        name=\"Extra Shading Pie Menu Items\",\n        description=(\n            \"Show additional options in the shading menu (\'Z\')\"\n        ),\n        default=False,\n        update=update_fn,\n    )\n    v3d_tilde_action: EnumProperty(\n        name=\"Tilde Action\",\n        items=(\n            (\'VIEW\', \"Navigate\",\n             \"View operations (useful for keyboards without a numpad)\",\n             0),\n            (\'GIZMO\', \"Gizmos\",\n             \"Control transform gizmos\",\n             1),\n        ),\n        description=(\n            \"Action when \'Tilde\' is pressed\"\n        ),\n        default=\'VIEW\',\n        update=update_fn,\n    )\n\n    v3d_mmb_action: EnumProperty(\n        name=\"MMB Action\",\n        items=(\n            (\'ORBIT\', \"Orbit\",\n             \"Orbit\",\n             0),\n            (\'PAN\', \"Pan\",\n             \"Set the view axis where each mouse direction always maps to the same axis\",\n             1),\n        ),\n        description=(\n            \"The action when Middle-Mouse dragging in the viewport. Shift-Middle-Mouse is used for the other action\"\n        ),\n        update=update_fn,\n    )\n\n    v3d_alt_mmb_drag_action: EnumProperty(\n        name=\"Alt-MMB Drag Action\",\n        items=(\n            (\'RELATIVE\', \"Relative\",\n             \"Set the view axis where each mouse direction maps to an axis relative to the current orientation\",\n             0),\n            (\'ABSOLUTE\', \"Absolute\",\n             \"Set the view axis where each mouse direction always maps to the same axis\",\n             1),\n        ),\n        description=(\n            \"Action when Alt-MMB dragging in the 3D viewport\"\n        ),\n        update=update_fn,\n    )\n\n    # Developer note, this is an experemental option.\n    use_pie_click_drag: BoolProperty(\n        name=\"Pie Menu on Drag\",\n        description=(\n            \"Activate some pie menus on drag,\\n\"\n            \"allowing the tapping the same key to have a secondary action.\\n\"\n            \"\\n\"\n            \"\u2022 Tapping Tab in the 3D view toggles edit-mode, drag for mode menu.\\n\"\n            \"\u2022 Tapping Z in the 3D view toggles wireframe, drag for draw modes.\\n\"\n            \"\u2022 Tapping Tilde in the 3D view for first person navigation, drag for view axes\"\n        ),\n        default=False,\n        update=update_fn,\n    )\n\n    def draw(self, layout):\n        layout.use_property_split = True\n\n        is_select_left = (self.select_mouse == \'LEFT\')\n\n        # General settings.\n        col = layout.column()\n        col.row().prop(self, \"select_mouse\", text=\"Select with Mouse Button\", expand=True)\n        col.row().prop(self, \"spacebar_action\", text=\"Spacebar Action\", expand=True)\n        if is_select_left:\n            col.row().prop(self, \"gizmo_action\", text=\"Activate Gizmo Event\", expand=True)\n\n        # Checkboxes sub-layout.\n        col = layout.column()\n        sub = col.column(align=True)\n        sub.prop(self, \"use_select_all_toggle\")\n\n        # 3DView settings.\n        col = layout.column()\n        col.label(text=\"3D View\")\n        col.row().prop(self, \"v3d_tilde_action\", text=\"Grave Accent / Tilde Action\", expand=True)\n        col.row().prop(self, \"v3d_mmb_action\", text=\"Middle Mouse Action\", expand=True)\n        col.row().prop(self, \"v3d_alt_mmb_drag_action\", text=\"Alt Middle Mouse Drag Action\", expand=True)\n\n        # Checkboxes sub-layout.\n        col = layout.column()\n        sub = col.column(align=True)\n        sub.prop(self, \"use_v3d_tab_menu\")\n        sub.prop(self, \"use_pie_click_drag\")\n        sub.prop(self, \"use_v3d_shade_ex_pie\")\n\n\n\nAPP = \"/Applications/Blender-2.83-alpha/Blender.app/Contents/Resources/2.83/\"\nblender_default = bpy.utils.execfile(os.path.join(APP, \"scripts/presets/keyconfig/keymap_data\", \"blender_default.py\"))\n\n\ndef load():\n    from sys import platform\n    from bpy import context\n    from bl_keymap_utils.io import keyconfig_init_from_data\n\n    prefs = context.preferences\n    kc = context.window_manager.keyconfigs.new(IDNAME)\n    kc_prefs = kc.preferences\n\n    keyconfig_data = blender_default.generate_keymaps(\n        blender_default.Params(\n            select_mouse=kc_prefs.select_mouse,\n            use_mouse_emulate_3_button=(\n                prefs.inputs.use_mouse_emulate_3_button and\n                prefs.inputs.mouse_emulate_3_button_modifier == \'ALT\'\n            ),\n            spacebar_action=kc_prefs.spacebar_action,\n            v3d_tilde_action=kc_prefs.v3d_tilde_action,\n            use_v3d_mmb_pan=(kc_prefs.v3d_mmb_action == \'PAN\'),\n            v3d_alt_mmb_drag_action=kc_prefs.v3d_alt_mmb_drag_action,\n            use_select_all_toggle=kc_prefs.use_select_all_toggle,\n            use_v3d_tab_menu=kc_prefs.use_v3d_tab_menu,\n            use_v3d_shade_ex_pie=kc_prefs.use_v3d_shade_ex_pie,\n            use_gizmo_drag=(\n                kc_prefs.select_mouse == \'LEFT\' and\n                kc_prefs.gizmo_action == \'DRAG\'\n            ),\n            use_pie_click_drag=kc_prefs.use_pie_click_drag,\n        ),\n    )\n\n    if platform == \'darwin\':\n        from bl_keymap_utils.platform_helpers import keyconfig_data_oskey_from_ctrl_for_macos\n        keyconfig_data = keyconfig_data_oskey_from_ctrl_for_macos(keyconfig_data)\n\n    keyconfig_init_from_data(kc, keyconfig_data)\n\n\n")

        
        for km, _kc_x in export_keymaps:
            km = km.active()
            fw("(")
            fw(f"\"{km.name:s}\",\n")
            fw(f"{indent(2)}" "{")
            fw(f"\"space_type\": '{km.space_type:s}'")
            fw(f", \"region_type\": '{km.region_type:s}'")
            # We can detect from the kind of items.
            if km.is_modal:
                fw(", \"modal\": True")
            fw("},\n")
            fw(f"{indent(2)}" "{")
            is_modal = km.is_modal
            fw(f"\"items\":\n")
            fw(f"{indent(3)}[")
            for kmi in km.keymap_items:
                if is_modal:
                    kmi_id = kmi.propvalue
                else:
                    kmi_id = kmi.idname
                fw(f"(")
                kmi_args = kmi_args_as_data(kmi)
                kmi_data = _kmi_attrs_or_none(4, kmi)
                fw(f"\"{kmi_id:s}\"")
                if kmi_data is None:
                    fw(f", ")
                else:
                    fw(",\n" f"{indent(5)}")

                fw(kmi_args)
                if kmi_data is None:
                    fw(", None),\n")
                else:
                    fw(",\n")
                    fw(f"{indent(5)}" "{")
                    fw(kmi_data)
                    fw(f"{indent(6)}")
                    fw("},\n" f"{indent(5)}")
                    fw("),\n")
                fw(f"{indent(4)}")
            fw("],\n" f"{indent(3)}")
            fw("},\n" f"{indent(2)}")
            fw("),\n" f"{indent(1)}")

        fw("]\n")
        fw("\n\n")
        
        kc_prefs = kc.preferences
        
        fw("def setDefaults():\n")
        fw("    context = bpy.context\n")
        fw("    kc = context.window_manager.keyconfigs[\'%s\']\n" % kc.name)
        fw("    kc_prefs = kc.preferences\n\n")
        fw("    kc_prefs.spacebar_action = \'%s\'\n" % kc_prefs.spacebar_action)
        fw("    kc_prefs.v3d_tilde_action = \'%s\'\n" % kc_prefs.v3d_tilde_action)
        fw("    kc_prefs.v3d_mmb_action = \'%s\'\n" % kc_prefs.v3d_mmb_action)
        fw("    kc_prefs.v3d_alt_mmb_drag_action = \'%s\'\n" % kc_prefs.v3d_alt_mmb_drag_action)
        fw("    kc_prefs.use_select_all_toggle = %s\n" % kc_prefs.use_select_all_toggle)
        fw("    kc_prefs.use_v3d_tab_menu = %s\n" % kc_prefs.use_v3d_tab_menu)
        fw("    kc_prefs.use_v3d_shade_ex_pie = %s\n" % kc_prefs.use_v3d_shade_ex_pie)
        fw("    kc_prefs.gizmo_action = \'%s\'\n" % kc_prefs.gizmo_action)
        fw("    kc_prefs.use_pie_click_drag = %s\n\n" % kc_prefs.use_pie_click_drag)
        fw("if __name__ == \"__main__\":\n")
        fw("    bpy.utils.register_class(Prefs)\n\n")
        fw("    load()\n")
        fw("    import os\n")
        fw("    from bl_keymap_utils.io import keyconfig_import_from_data\n")
        fw("    keyconfig_import_from_data(os.path.splitext(os.path.basename(__file__))[0], keyconfig_data)\n")
        fw("    setDefaults()")


- -----------------------------------------------------------------------------
- Import Functions

def _kmi_props_setattr(kmi_props, attr, value):
    if type(value) is list:
        kmi_subprop = getattr(kmi_props, attr)
        for subattr, subvalue in value:
            _kmi_props_setattr(kmi_subprop, subattr, subvalue)
        return

    try:
        setattr(kmi_props, attr, value)
    except AttributeError:
        print(f"Warning: property '{attr}' not found in keymap item '{kmi_props.__class__.__name__}'")
    except Exception as ex:
        print(f"Warning: {ex!r}")


def keymap_init_from_data(km, km_items, is_modal=False):
    new_fn = getattr(km.keymap_items, "new_modal" if is_modal else "new")
    for (kmi_idname, kmi_args, kmi_data) in km_items:
        kmi = new_fn(kmi_idname, **kmi_args)
        if kmi_data is not None:
            if not kmi_data.get("active", True):
                kmi.active = False
            kmi_props_data = kmi_data.get("properties", None)
            if kmi_props_data is not None:
                kmi_props = kmi.properties
                assert type(kmi_props_data) is list
                for attr, value in kmi_props_data:
                    _kmi_props_setattr(kmi_props, attr, value)


def keyconfig_init_from_data(kc, keyconfig_data):
    - Load data in the format defined above.
    #
    # Runs at load time, keep this fast!
    for (km_name, km_args, km_content) in keyconfig_data:
        km = kc.keymaps.new(km_name, **km_args)
        km_items = km_content["items"]
        - Check here instead of inside 'keymap_init_from_data'
        - because we want to allow both tuple & list types in that case.
        #
        - For full keymaps, ensure these are always lists to allow for extending them
        # in a generic way that doesn't have to check for the type each time.
        assert type(km_items) is list
        keymap_init_from_data(km, km_items, is_modal=km_args.get("modal", False))


def keyconfig_import_from_data(name, keyconfig_data):
    - Load data in the format defined above.
    #
    # Runs at load time, keep this fast!

    import bpy
    wm = bpy.context.window_manager
    kc = wm.keyconfigs.new(name)
    keyconfig_init_from_data(kc, keyconfig_data)
    return kc


- -----------------------------------------------------------------------------
- Utility Functions

def keyconfig_merge(kc1, kc2):
    """ note: kc1 takes priority over kc2
    """
    kc1_names = {km.name for km in kc1.keymaps}
    merged_keymaps = [(km, kc1) for km in kc1.keymaps]
    if kc1 != kc2:
        merged_keymaps.extend(
            (km, kc2)
            for km in kc2.keymaps
            if km.name not in kc1_names
        )
    return merged_keymaps

@JoelArt Hi Joel, i havent tested it yet in newer versions though. I replace the file located in this folder *Fill XX with personal and bl version* ``` C:\Program Files\Blender Foundation\Blender XXX\XXX\scripts\modules\bl_keymap_utils ``` Be sure to either move that old file or rename it just in case it does break something also test it properly. I ran it a couple times and didnt see weird behavior, though i didnt check all shortcuts ofcourse. I randomly tried as many as i could and they seemed to work. I also check one of the old keymaps stored in the user-folder. *Fill XX with personal and bl version* ``` C:\Users\XXXXXX\AppData\Roaming\Blender Foundation\Blender\XXX\scripts\presets\keyconfig ``` You could also try opening one of the personal keymaps in a code-editor which allows you to compare them. Then see if they are different, you would do this by first saving a keymap without this new io.py, so save say "keymap-A" then replace (keep the old one!!!!) the io.py and name this "keymap-B" then compared them. The new version should have added code which i show below with the lien numbers. I just check the io.py in 2.91 and they have added some lines to io.py, it now sorts the keymaps when storing, allows for easier comparing. Another method is by adding the top part in case you want to edit it, but you would need to do that every time, then reload Blender. I think this is to tedious to do, the thing is each time you press something in the at top part, it loads and adjust all shortcuts on the fly. I cant remember how i did that part. I just looked at their base preset and it would take quite some time for me to figure it out again. What you would need to is is copy/paste # 157, the part which says ''fw("import os\n.....``` and then lots code between the double quotation marks. You also need to add #206 to #231 and replace that with #212. I added the adjusted version here below, i wasnt sure you would be able to do it yourself. Again, make a backup or rename that io.py before you do this, otherwise you could break the ability to properly save keymaps in the future ``` - ##### BEGIN GPL LICENSE BLOCK ##### # - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. # - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. # - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ##### END GPL LICENSE BLOCK ##### # <pep8 compliant> - ----------------------------------------------------------------------------- - Export Functions __all__ = ( "keyconfig_export_as_data", "keyconfig_import_from_data", "keyconfig_init_from_data", "keyconfig_merge", "keymap_init_from_data", ) def indent(levels): return levels * " " def round_float_32(f): from struct import pack, unpack return unpack("f", pack("f", f))[0] def repr_f32(f): f_round = round_float_32(f) f_str = repr(f) f_str_frac = f_str.partition(".")[2] if not f_str_frac: return f_str for i in range(1, len(f_str_frac)): f_test = round(f, i) f_test_round = round_float_32(f_test) if f_test_round == f_round: return "%.*f" % (i, f_test) return f_str def kmi_args_as_data(kmi): s = [ f"\"type\": '{kmi.type}'", f"\"value\": '{kmi.value}'" ] if kmi.any: s.append("\"any\": True") else: if kmi.shift: s.append("\"shift\": True") if kmi.ctrl: s.append("\"ctrl\": True") if kmi.alt: s.append("\"alt\": True") if kmi.oskey: s.append("\"oskey\": True") if kmi.key_modifier and kmi.key_modifier != 'NONE': s.append(f"\"key_modifier\": '{kmi.key_modifier}'") return "{" + ", ".join(s) + "}" def _kmi_properties_to_lines_recursive(level, properties, lines): from bpy.types import OperatorProperties def string_value(value): if isinstance(value, (str, bool, int, set)): return repr(value) elif isinstance(value, float): return repr_f32(value) elif getattr(value, '__len__', False): return repr(tuple(value)) raise Exception(f"Export key configuration: can't write {value!r}") for pname in properties.bl_rna.properties.keys(): if pname != "rna_type": value = getattr(properties, pname) if isinstance(value, OperatorProperties): lines_test = [] _kmi_properties_to_lines_recursive(level + 2, value, lines_test) if lines_test: lines.append(f"(") lines.append(f"\"{pname}\",\n") lines.append(f"{indent(level + 3)}" "[") lines.extend(lines_test) lines.append("],\n") lines.append(f"{indent(level + 3)}" "),\n" f"{indent(level + 2)}") del lines_test elif properties.is_property_set(pname): value = string_value(value) lines.append((f"(\"{pname}\", {value:s}),\n" f"{indent(level + 2)}")) def _kmi_properties_to_lines(level, kmi_props, lines): if kmi_props is None: return lines_test = [f"\"properties\":\n" f"{indent(level + 1)}" "["] _kmi_properties_to_lines_recursive(level, kmi_props, lines_test) if len(lines_test) > 1: lines_test.append("],\n") lines.extend(lines_test) def _kmi_attrs_or_none(level, kmi): lines = [] _kmi_properties_to_lines(level + 1, kmi.properties, lines) if kmi.active is False: lines.append(f"{indent(level)}\"active\":" "False,\n") if not lines: return None return "".join(lines) def keyconfig_export_as_data(wm, kc, filepath, *, all_keymaps=False): # Alternate format - Generate a list of keymaps to export: # - First add all user_modified keymaps (found in keyconfigs.user.keymaps list), - then add all remaining keymaps from the currently active custom keyconfig. # - Sort the resulting list according to top context name, - while this isn't essential, it makes comparing keymaps simpler. # - This will create a final list of keymaps that can be used as a "diff" against - the default blender keyconfig, recreating the current setup from a fresh blender # without needing to export keymaps which haven't been edited. class FakeKeyConfig: keymaps = [] edited_kc = FakeKeyConfig() for km in wm.keyconfigs.user.keymaps: if all_keymaps or km.is_user_modified: edited_kc.keymaps.append(km) # merge edited keymaps with non-default keyconfig, if it exists if kc != wm.keyconfigs.default: export_keymaps = keyconfig_merge(edited_kc, kc) else: export_keymaps = keyconfig_merge(edited_kc, edited_kc) - Sort the keymap list by top context name before exporting, - not essential, just convenient to order them predictably. export_keymaps.sort(key=lambda k: k[0].name) with open(filepath, "w", encoding="utf-8") as fh: fw = fh.write fw("keyconfig_data = \\\n[") fw("import os\nimport bpy\nfrom bpy.props import (\n BoolProperty,\n EnumProperty,\n)\n\nDIRNAME, FILENAME = os.path.split(__file__)\nIDNAME = os.path.splitext(FILENAME)[0]\n\ndef update_fn(_self, _context):\n load()\n\n\nclass Prefs(bpy.types.KeyConfigPreferences):\n bl_idname = IDNAME\n\n select_mouse: EnumProperty(\n name=\"Select Mouse\",\n items=(\n (\'LEFT\', \"Left\",\n \"Use left mouse button for selection. \"\n \"The standard behavior that works well for mouse, trackpad and tablet devices\"),\n (\'RIGHT\', \"Right\",\n \"Use right mouse button for selection, and left mouse button for actions. \"\n \"This works well primarily for keyboard and mouse devices\"),\n ),\n description=(\n \"Mouse button used for selection\"\n ),\n update=update_fn,\n )\n spacebar_action: EnumProperty(\n name=\"Spacebar Action\",\n items=(\n (\'PLAY\', \"Play\",\n \"Toggle animation playback \"\n \"(\'Shift-Space\' for Tools)\",\n 1),\n (\'TOOL\', \"Tools\",\n \"Open the popup tool-bar\\n\"\n \"When \'Space\' is held and used as a modifier:\\n\"\n \"\u2022 Pressing the tools binding key switches to it immediately.\\n\"\n \"\u2022 Dragging the cursor over a tool and releasing activates it (like a pie menu).\\n\"\n \"For Play use \'Shift-Space\'\",\n 0),\n (\'SEARCH\', \"Search\",\n \"Open the operator search popup\",\n 2),\n ),\n description=(\n \"Action when \'Space\' is pressed\"\n ),\n default=\'PLAY\',\n update=update_fn,\n )\n use_select_all_toggle: BoolProperty(\n name=\"Select All Toggles\",\n description=(\n \"Causes select-all (\'A\' key) to de-select in the case a selection exists\"\n ),\n default=False,\n update=update_fn,\n )\n\n gizmo_action: EnumProperty(\n name=\"Activate Gizmo\",\n items=(\n (\'PRESS\', \"Press\", \"Press causes immediate activation, preventing click being passed to the tool\"),\n (\'DRAG\', \"Drag\", \"Drag allows click events to pass through to the tool, adding a small delay\"),\n ),\n description=\"Activation event for gizmos that support drag motion\",\n default=\'DRAG\',\n update=update_fn,\n )\n\n # 3D View\n use_v3d_tab_menu: BoolProperty(\n name=\"Tab for Pie Menu\",\n description=(\n \"Causes tab to open pie menu (swaps \'Tab\' / \'Ctrl-Tab\')\"\n ),\n default=False,\n update=update_fn,\n )\n use_v3d_shade_ex_pie: BoolProperty(\n name=\"Extra Shading Pie Menu Items\",\n description=(\n \"Show additional options in the shading menu (\'Z\')\"\n ),\n default=False,\n update=update_fn,\n )\n v3d_tilde_action: EnumProperty(\n name=\"Tilde Action\",\n items=(\n (\'VIEW\', \"Navigate\",\n \"View operations (useful for keyboards without a numpad)\",\n 0),\n (\'GIZMO\', \"Gizmos\",\n \"Control transform gizmos\",\n 1),\n ),\n description=(\n \"Action when \'Tilde\' is pressed\"\n ),\n default=\'VIEW\',\n update=update_fn,\n )\n\n v3d_mmb_action: EnumProperty(\n name=\"MMB Action\",\n items=(\n (\'ORBIT\', \"Orbit\",\n \"Orbit\",\n 0),\n (\'PAN\', \"Pan\",\n \"Set the view axis where each mouse direction always maps to the same axis\",\n 1),\n ),\n description=(\n \"The action when Middle-Mouse dragging in the viewport. Shift-Middle-Mouse is used for the other action\"\n ),\n update=update_fn,\n )\n\n v3d_alt_mmb_drag_action: EnumProperty(\n name=\"Alt-MMB Drag Action\",\n items=(\n (\'RELATIVE\', \"Relative\",\n \"Set the view axis where each mouse direction maps to an axis relative to the current orientation\",\n 0),\n (\'ABSOLUTE\', \"Absolute\",\n \"Set the view axis where each mouse direction always maps to the same axis\",\n 1),\n ),\n description=(\n \"Action when Alt-MMB dragging in the 3D viewport\"\n ),\n update=update_fn,\n )\n\n # Developer note, this is an experemental option.\n use_pie_click_drag: BoolProperty(\n name=\"Pie Menu on Drag\",\n description=(\n \"Activate some pie menus on drag,\\n\"\n \"allowing the tapping the same key to have a secondary action.\\n\"\n \"\\n\"\n \"\u2022 Tapping Tab in the 3D view toggles edit-mode, drag for mode menu.\\n\"\n \"\u2022 Tapping Z in the 3D view toggles wireframe, drag for draw modes.\\n\"\n \"\u2022 Tapping Tilde in the 3D view for first person navigation, drag for view axes\"\n ),\n default=False,\n update=update_fn,\n )\n\n def draw(self, layout):\n layout.use_property_split = True\n\n is_select_left = (self.select_mouse == \'LEFT\')\n\n # General settings.\n col = layout.column()\n col.row().prop(self, \"select_mouse\", text=\"Select with Mouse Button\", expand=True)\n col.row().prop(self, \"spacebar_action\", text=\"Spacebar Action\", expand=True)\n if is_select_left:\n col.row().prop(self, \"gizmo_action\", text=\"Activate Gizmo Event\", expand=True)\n\n # Checkboxes sub-layout.\n col = layout.column()\n sub = col.column(align=True)\n sub.prop(self, \"use_select_all_toggle\")\n\n # 3DView settings.\n col = layout.column()\n col.label(text=\"3D View\")\n col.row().prop(self, \"v3d_tilde_action\", text=\"Grave Accent / Tilde Action\", expand=True)\n col.row().prop(self, \"v3d_mmb_action\", text=\"Middle Mouse Action\", expand=True)\n col.row().prop(self, \"v3d_alt_mmb_drag_action\", text=\"Alt Middle Mouse Drag Action\", expand=True)\n\n # Checkboxes sub-layout.\n col = layout.column()\n sub = col.column(align=True)\n sub.prop(self, \"use_v3d_tab_menu\")\n sub.prop(self, \"use_pie_click_drag\")\n sub.prop(self, \"use_v3d_shade_ex_pie\")\n\n\n\nAPP = \"/Applications/Blender-2.83-alpha/Blender.app/Contents/Resources/2.83/\"\nblender_default = bpy.utils.execfile(os.path.join(APP, \"scripts/presets/keyconfig/keymap_data\", \"blender_default.py\"))\n\n\ndef load():\n from sys import platform\n from bpy import context\n from bl_keymap_utils.io import keyconfig_init_from_data\n\n prefs = context.preferences\n kc = context.window_manager.keyconfigs.new(IDNAME)\n kc_prefs = kc.preferences\n\n keyconfig_data = blender_default.generate_keymaps(\n blender_default.Params(\n select_mouse=kc_prefs.select_mouse,\n use_mouse_emulate_3_button=(\n prefs.inputs.use_mouse_emulate_3_button and\n prefs.inputs.mouse_emulate_3_button_modifier == \'ALT\'\n ),\n spacebar_action=kc_prefs.spacebar_action,\n v3d_tilde_action=kc_prefs.v3d_tilde_action,\n use_v3d_mmb_pan=(kc_prefs.v3d_mmb_action == \'PAN\'),\n v3d_alt_mmb_drag_action=kc_prefs.v3d_alt_mmb_drag_action,\n use_select_all_toggle=kc_prefs.use_select_all_toggle,\n use_v3d_tab_menu=kc_prefs.use_v3d_tab_menu,\n use_v3d_shade_ex_pie=kc_prefs.use_v3d_shade_ex_pie,\n use_gizmo_drag=(\n kc_prefs.select_mouse == \'LEFT\' and\n kc_prefs.gizmo_action == \'DRAG\'\n ),\n use_pie_click_drag=kc_prefs.use_pie_click_drag,\n ),\n )\n\n if platform == \'darwin\':\n from bl_keymap_utils.platform_helpers import keyconfig_data_oskey_from_ctrl_for_macos\n keyconfig_data = keyconfig_data_oskey_from_ctrl_for_macos(keyconfig_data)\n\n keyconfig_init_from_data(kc, keyconfig_data)\n\n\n") for km, _kc_x in export_keymaps: km = km.active() fw("(") fw(f"\"{km.name:s}\",\n") fw(f"{indent(2)}" "{") fw(f"\"space_type\": '{km.space_type:s}'") fw(f", \"region_type\": '{km.region_type:s}'") # We can detect from the kind of items. if km.is_modal: fw(", \"modal\": True") fw("},\n") fw(f"{indent(2)}" "{") is_modal = km.is_modal fw(f"\"items\":\n") fw(f"{indent(3)}[") for kmi in km.keymap_items: if is_modal: kmi_id = kmi.propvalue else: kmi_id = kmi.idname fw(f"(") kmi_args = kmi_args_as_data(kmi) kmi_data = _kmi_attrs_or_none(4, kmi) fw(f"\"{kmi_id:s}\"") if kmi_data is None: fw(f", ") else: fw(",\n" f"{indent(5)}") fw(kmi_args) if kmi_data is None: fw(", None),\n") else: fw(",\n") fw(f"{indent(5)}" "{") fw(kmi_data) fw(f"{indent(6)}") fw("},\n" f"{indent(5)}") fw("),\n") fw(f"{indent(4)}") fw("],\n" f"{indent(3)}") fw("},\n" f"{indent(2)}") fw("),\n" f"{indent(1)}") fw("]\n") fw("\n\n") kc_prefs = kc.preferences fw("def setDefaults():\n") fw(" context = bpy.context\n") fw(" kc = context.window_manager.keyconfigs[\'%s\']\n" % kc.name) fw(" kc_prefs = kc.preferences\n\n") fw(" kc_prefs.spacebar_action = \'%s\'\n" % kc_prefs.spacebar_action) fw(" kc_prefs.v3d_tilde_action = \'%s\'\n" % kc_prefs.v3d_tilde_action) fw(" kc_prefs.v3d_mmb_action = \'%s\'\n" % kc_prefs.v3d_mmb_action) fw(" kc_prefs.v3d_alt_mmb_drag_action = \'%s\'\n" % kc_prefs.v3d_alt_mmb_drag_action) fw(" kc_prefs.use_select_all_toggle = %s\n" % kc_prefs.use_select_all_toggle) fw(" kc_prefs.use_v3d_tab_menu = %s\n" % kc_prefs.use_v3d_tab_menu) fw(" kc_prefs.use_v3d_shade_ex_pie = %s\n" % kc_prefs.use_v3d_shade_ex_pie) fw(" kc_prefs.gizmo_action = \'%s\'\n" % kc_prefs.gizmo_action) fw(" kc_prefs.use_pie_click_drag = %s\n\n" % kc_prefs.use_pie_click_drag) fw("if __name__ == \"__main__\":\n") fw(" bpy.utils.register_class(Prefs)\n\n") fw(" load()\n") fw(" import os\n") fw(" from bl_keymap_utils.io import keyconfig_import_from_data\n") fw(" keyconfig_import_from_data(os.path.splitext(os.path.basename(__file__))[0], keyconfig_data)\n") fw(" setDefaults()") - ----------------------------------------------------------------------------- - Import Functions def _kmi_props_setattr(kmi_props, attr, value): if type(value) is list: kmi_subprop = getattr(kmi_props, attr) for subattr, subvalue in value: _kmi_props_setattr(kmi_subprop, subattr, subvalue) return try: setattr(kmi_props, attr, value) except AttributeError: print(f"Warning: property '{attr}' not found in keymap item '{kmi_props.__class__.__name__}'") except Exception as ex: print(f"Warning: {ex!r}") def keymap_init_from_data(km, km_items, is_modal=False): new_fn = getattr(km.keymap_items, "new_modal" if is_modal else "new") for (kmi_idname, kmi_args, kmi_data) in km_items: kmi = new_fn(kmi_idname, **kmi_args) if kmi_data is not None: if not kmi_data.get("active", True): kmi.active = False kmi_props_data = kmi_data.get("properties", None) if kmi_props_data is not None: kmi_props = kmi.properties assert type(kmi_props_data) is list for attr, value in kmi_props_data: _kmi_props_setattr(kmi_props, attr, value) def keyconfig_init_from_data(kc, keyconfig_data): - Load data in the format defined above. # # Runs at load time, keep this fast! for (km_name, km_args, km_content) in keyconfig_data: km = kc.keymaps.new(km_name, **km_args) km_items = km_content["items"] - Check here instead of inside 'keymap_init_from_data' - because we want to allow both tuple & list types in that case. # - For full keymaps, ensure these are always lists to allow for extending them # in a generic way that doesn't have to check for the type each time. assert type(km_items) is list keymap_init_from_data(km, km_items, is_modal=km_args.get("modal", False)) def keyconfig_import_from_data(name, keyconfig_data): - Load data in the format defined above. # # Runs at load time, keep this fast! import bpy wm = bpy.context.window_manager kc = wm.keyconfigs.new(name) keyconfig_init_from_data(kc, keyconfig_data) return kc - ----------------------------------------------------------------------------- - Utility Functions def keyconfig_merge(kc1, kc2): """ note: kc1 takes priority over kc2 """ kc1_names = {km.name for km in kc1.keymaps} merged_keymaps = [(km, kc1) for km in kc1.keymaps] if kc1 != kc2: merged_keymaps.extend( (km, kc2) for km in kc2.keymaps if km.name not in kc1_names ) return merged_keymaps ```

@RomboutVersluijs Versluijs (rombout) Thank you!

@RomboutVersluijs Versluijs (rombout) Thank you!

Added subscriber: @Vyach

Added subscriber: @Vyach

In #65121#895037, @brecht wrote:
It doesn't solve the issue, but it means it's not considered a bug and should not be in our bug tracker, it's a feature request.

More like upgrading current behavior to full version.
But you are right, it is not for bugtracker. And it is weird, that there is no such request on RCS

> In #65121#895037, @brecht wrote: > It doesn't solve the issue, but it means it's not considered a bug and should not be in our bug tracker, it's a feature request. More like upgrading current behavior to full version. But you are right, it is not for bugtracker. And it is weird, that there is no such request on RCS
Member

Added subscribers: @costa, @PratikPB2123, @Xorrito

Added subscribers: @costa, @PratikPB2123, @Xorrito

This exact problem just happened to me as I imported my shortcuts from Blender 3.3.1 to 3.5
The same thing happened in 3.3.1 since I exported.
I don't understand. Where can I report this as a bug and how can I fix this behaviour?

Any news or updates on this?

This exact problem just happened to me as I imported my shortcuts from Blender 3.3.1 to 3.5 The same thing happened in 3.3.1 since I exported. I don't understand. Where can I report this as a bug and how can I fix this behaviour? Any news or updates on this?

Can we reopen this issue. Even if this is considered a feature request it behaves like a bug from a user perspective.

Can we reopen this issue. Even if this is considered a feature request it behaves like a bug from a user perspective.

For user feedback and feature requests, please use other channels: https://developer.blender.org/docs/handbook/communication/user_feedback/

For user feedback and feature requests, please use other channels: https://developer.blender.org/docs/handbook/communication/user_feedback/
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
15 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#65121
No description provided.