- Undocumented Matlab - https://undocumentedmatlab.com -

Figure keypress modifiers

Matlab figures have a documented property called SelectionType [1] that returns information about keypress modifiers such as or that were pressed during mouse clicks. Using this property has several drawbacks IMHO:

% Documented: we need to get the modifier data in two different manners
set(gcf, 'WindowButtonDownFcn', @(h,e) disp(get(gcf,'SelectionType')));  % mouse clicks: displays a single string: 'normal','alt','extend' or 'open'
set(gcf, 'WindowKeyPressFcn',   @(h,e) disp(e.Modifier));  % keyboard clicks: displays a cell-array of strings, e.g. {'shift','control','alt'}

The inconsistency between the functionality for mouse and keyboard clicks, and the limitations of the SelectionType property, are striking and most annoying. Some might say that it’s been like this for the past 2 decades so Matlab users have probably gotten used to it by now. But I must admit that after over 2 decades with Matlab I still need to refer to the documentation to figure out the correct behavior. Maybe that’s because I’m getting old, or maybe it means that the behavior is indeed not as intuitive as one could hope for.
For this reason, I was very happy to discover several years ago that there was a much simpler, easier and consistent solution, although (alas) undocumented. The trick is to simply query the undocumented hidden figure property CurrentModifier: CurrentModifier is updated during both mouse and keyboard clicks, in the same consistent manner, in both cases returning the same cell-array of strings as the Modifier property of the standard key-press event:

% Undocumented: the following displays a cell-array of strings having a consistent format, e.g. {'shift','control','alt'}
set(gcf, 'WindowButtonDownFcn', @(h,e) disp(get(gcf,'CurrentModifier')));  % mouse clicks
set(gcf, 'WindowKeyPressFcn',   @(h,e) disp(get(gcf,'CurrentModifier')));  % keyboard clicks

Checking whether any modifier was pressed becomes trivial:

modifiers = get(gcf,'CurrentModifier');
wasShiftPressed = ismember('shift',   modifiers);  % true/false
wasCtrlPressed  = ismember('control', modifiers);  % true/false
wasAltPressed   = ismember('alt',     modifiers);  % true/false

Hurrah for simplicity and consistency!
Note that despite the fact that CurrentModifier is hidden and undocumented, it has existed as-is for many years, and even survived (unchanged) the major transition from HG1 to HG2 in R2014b. This has to mean that MathWorks recognized the importance of CurrentModifier and took the deliberate decision (and associate dev effort) to preserve it. So why wasn’t this useful property made documented ages ago, or at the very least at the HG2 transition point? I don’t have a good answer to this riddle.

6 Comments (Open | Close)

6 Comments To "Figure keypress modifiers"

#1 Comment By julien On November 10, 2015 @ 06:33

Indeed, this is convenient. However, when figure has not focus, ‘CurrentModifier’ property is not updated. So if you hold a modifier key when figure has not focus and you then clic in the figure, ‘CurrentModifier’ property is not correct. Do you know a way to fix this?

#2 Comment By Yair Altman On November 10, 2015 @ 07:35

You can use the KeyPressedCallback property at the Java-frame level, then you don’t have any of these limitations.

#3 Comment By julien On November 12, 2015 @ 13:44

Actually, when figure has not the focus, java ‘KeyPressed’ event is not triggered. So, impossible to know when the clic is done which modifiers are pressed…

#4 Comment By Yair Altman On November 12, 2015 @ 15:34

When the window does not have focus then it should not handle any key-press event. It is the responsibility of the window that does have the focus to process it.

#5 Comment By Daniel Castano On April 21, 2017 @ 10:42

This info has made may life so much easier in the past months…. thanks!

I’m wondering if the Figure class has some equivalent property for the behaviour of the mouse, i.e., a property that expresses if (in the moment of reading the property) the mouse is pressed, and which button.

#6 Comment By Heiko On February 1, 2018 @ 11:27

On a not directly related note, I found out that if you create a figure with an edit control and you enter the ‘@’ symbol, MatLab closes like it would with the CTRL+Q shortcut. If MatLab is configured to not ask for confirmation, it simply closes without warning.

Mathworks explains this with the CTRL+Q event forwarded from the figure to the command window. This behavior seems to exist since R2014b. MatLab doesn’t seem to make a distinction between the modifiers (‘@’ is CTRL+ALT+Q). The official workaround is to populate the file menu either by clicking on it, or programmatically like this:

f = figure;
filemenufcn(f, 'FilePost');
uicontrol(f,'Style','edit')

Alternatively, the confirmation for closing should be activated. Once cancelling the confirmation, the ‘@’ symbol can be used without the effect.

IMHO, this is a critical bug for GUIs using edit fields for email addresses and the like, because data loss is very likely.