Figure keypress modifiers

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

  • The reported SelectionType value is 'extend' for shift-clicks and 'alt' for ctrl-clicks, not very intuitive.
  • There is no support for alt-clicks, which are reported as regular ('normal') mouse clicks. In fact, 'alt' is reported for ctrl-clicks rather than for alt-clicks, which is very confusing.
  • There is no support for modifier combinations such as ctrl+shift-click. These again are reported as regular ('normal') mouse clicks.
  • SelectionType is only updated for mouse clicks, not for keyboard clicks. This again is very confusing. To extract the keypress modifier for key-click events we need to get the Modifier property of the key-press event, and this returns a cell-array of strings (e.g., {'shift','control','alt'}). Note that in this case, unlike SelectionType, the modifier names are as expected, alt-clicks is recognised and so are modifier combinations.
% 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.

Categories: Figure window, GUI, Medium risk of breaking in future versions, Undocumented feature

Tags: , , , ,

Bookmark and SharePrint Print

7 Responses to Figure keypress modifiers

  1. julien says:

    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?

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

    • julien says:

      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…

    • 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.

  2. Daniel Castano says:

    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.

  3. Heiko says:

    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.

  4. Eric says:

    this save me a lot of time, thank you very much!

Leave a Reply

Your email address will not be published. Required fields are marked *