Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Monster refactor of shortcut management #1117

Merged
merged 13 commits into from
Jul 14, 2022

Conversation

lmoureaux
Copy link
Contributor

@lmoureaux lmoureaux commented Jul 10, 2022

Closes #1090 and more bugs I spotted while going through the code.
Closes #1088

See some detailed explanations in commit messages.

Things to test:

  • Check that the defaults make sense
  • Try all shortcuts, make sure they do something
  • Change shortcuts and repeat the above, including assigning a mouse button to keyboard-like shortcuts (e.g. Reload Tileset) and a key sequence to mouse-like shortcuts (e.g. Scroll Map)
  • Do it with different themes
  • Check that the shortcuts are restored correctly on restart

Assigning two reviewers so you can split the work if you like...

Note: the on-disk format of shortcuts has changed and there's no backward compatibility code

@lmoureaux
Copy link
Contributor Author

The clang failure is llvm/llvm-project#48582, I wonder how it succeeds at all on Linux.

lmoureaux added a commit to lmoureaux/freeciv21 that referenced this pull request Jul 10, 2022
Strangely enough, other versions of clang work fine...

See longturn#1117.
lmoureaux added 13 commits July 13, 2022 00:48
The code was needlessly convoluted. There was also a bug when "changing" the
shortcut to the value used immediately before.

See longturn#1090.
When shortcuts are reassigned by the user, the menu is searched for conflicting
shortcuts. If any conflict is found, the user gets an error message. Skip such
checks when the user didn't change the shortcut (so we avoid prompting about
duplication with the shortcut we're not changing).

See longturn#1090.
The menu wasn't updated when the user changed a shortcut from the UI. Implement
it as well as we can without rebuilding the whole menu from scratch: look for
an action with the old shortcut, and change it to the new shortcut. It doesn't
work when the previous shortcut involves the mouse, as we can't guarantee that
we're changing the correct entry in that case.

See longturn#1090.
The way configurable shortcuts were stored had a number of bugs related to the
use of numerical key values. For instance, trying to set a shortcut to "+"
would result in "Shift++" (for keyboard "+") or "Num++" (for numpad "+"). This
shortcut was then only working when using Shift+numpad +, which is not what the
user entered.

Unfortunately, getting the "currently typed QKeySequence" is impossible in Qt.
The canonical (and only viable) way of letting the user enter a QKeySequence
without using or duplicating private Qt APIs is with QKeySequenceEdit.
Unfortunately QKeySequenceEdit is for key sequence only.

This commit rewrites the shortcut classes to:
- Store shortcuts as proper QKeySequences
- Use QKeySequenceEdit as the input widget, with some changes to allow for
  mouse input as well
- Fix various cases where duplicate shortcuts were misdetected

Not all functionality is available yet. In particular, shortcuts that are not
available through the menu cannot be triggered using the keyboard, and not all
shortcuts support being used with the mouse (this was already the case).

The file format of saved shortcuts has changed. No migration path is provided.

Closes longturn#1090.
- Store and pass shortcuts by value/reference, it's a POD type
- Encapsulation
Walking through the menu to update action shortcuts, as was done previously, is
very brittle and doesn't work well with mouse shortcuts (since QAction doesn't
support them). This commit moves most of the shortcut handling logic to
fc_shortcuts: once an action is registered with it, its shortcut will be
updated automatically.

We still need to walk the menu to find shortcuts between hard-coded shortcuts
and user input, but that's much less likely to break since these shortcuts are
guaranteed to be keyboard only.
Not all shortcuts are mapped to actions in the menu. They stopped working when
we transitionned to QKeySequence. Restore this functionality by creating
QShortcut objects as needed and routing their signals to the mapctrl.cpp
function that was handling them.

This patch destroys mouse handling, but it will be restored in the next patch,
and in a better way.
Make all mouse event handling go through fc_shortcuts, so we get a unified
interface firing the desired actions whether they are bound to mouse buttons or
keyboard shortcuts. Well, unified to some extent because not all actions use
QAction, but that's work for another day.
It was missing the modifier and conflicting with "Wait".
We were deleting all actions in the client, including those managed by a
submenu. Don't delete them after all (the submenu will be deleted anyway, which
will trigger the deletion of the action).
QSettings expects arrays to start at 0 and won't report the size otherwise. We
were starting it at 1 because of the unused SC_NONE as the first entry in the
shortcut_id enum. Remove it and shift all enumerators by one so the first is at
0.

This breaks compatibility with earlier versions, but we're using V2 now anyway.
The last shortcut wasn't loaded, leading to crashes and strange behavior. Make
sure it's loaded
Strangely enough, other versions of clang work fine...

See longturn#1117.
@lmoureaux lmoureaux force-pushed the bugfix/shortcuts-reassign branch from 82de508 to 9dc08c2 Compare July 12, 2022 23:28
@lmoureaux
Copy link
Contributor Author

Closes #1088

Copy link
Collaborator

@jwrober jwrober left a comment

Choose a reason for hiding this comment

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

seems to work for me. I changed a ton of the options and they stayed put after a restart of the client. I was able to test majority of them. Only one I couldn't was to explode a nuke. The only default I would change is the city output to Crtl-O instead of W

@lmoureaux
Copy link
Contributor Author

seems to work for me. I changed a ton of the options and they stayed put after a restart of the client. I was able to test majority of them. Only one I couldn't was to explode a nuke. The only default I would change is the city output to Crtl-O instead of W

Thanks! Ctrl+W is the shortcut inherited from the Gtk client, but we can indeed revise that some day.

@psampathkumar
Copy link
Contributor

I guess this is ready for merging. We can merge as soon as the commented out code is deleted.

@lmoureaux
Copy link
Contributor Author

I guess this is ready for merging. We can merge as soon as the commented out code is deleted.

Which commented code?

@lmoureaux lmoureaux merged commit 707a78d into longturn:master Jul 14, 2022
@lmoureaux lmoureaux deleted the bugfix/shortcuts-reassign branch July 14, 2022 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants