Getting the State of Modifier Keys (ctrl/cmd, shift, alt)

This is a snippet I like to use for easily accessing the state of modifier keys when a user runs a script. I figured I would post it here as I couldn't easily track it down when I needed it today and thought it might be useful to other folks as well.

def get_modifiers():
    """Returns state of modifier keys: ctrl, shift, alt
    
    Example Usage:
    ctrl, shift, alt = get_modifiers()
    """

    bc = c4d.BaseContainer()
    if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.BFM_INPUT_CHANNEL,bc):
        ctrl = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QCTRL
        shift = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QSHIFT
        alt = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QALT
        
    return ctrl, shift, alt

Not sure if I am right, but I think something changed in R20 (at least for C++).
These are 2 code snippets of the same functionality in one of my plugins, which had to be changed in R20 to make it work as expected. Again ... not sure if this applies to Python.

pre-R20

	BaseContainer channels;
	GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, channels);
	Bool shiftModifier = channels.GetInt32(BFM_INPUT_QUALIFIER) & QSHIFT;
	Bool ctrlModifier = channels.GetInt32(BFM_INPUT_QUALIFIER) & QCTRL;

R20

	BaseContainer channels;
	GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, channels);
	Bool shiftModifier = (channels.GetInt32(BFM_INPUT_QUALIFIER) & QSHIFT) != 0;
	Bool ctrlModifier = (channels.GetInt32(BFM_INPUT_QUALIFIER) & QCTRL) != 0;

hello,

I've moved this topic to this category.

Thanks for sharing your snippet.

I will probably go this way to have Boolean and not "value". Same in c++ check != 0 i will go with == QCTRL ans so on.

        ctrl = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QCTRL == c4d.QCTRL
        shift = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QSHIFT == c4d.QSHIFT
        alt = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QALT == c4d.QALT

Regarding the pre-R20 and r20 code i don't have any idea instead that storing bool in a bool (0 or 1) make more sense.
In your code pre-R20 you were sending value > 1 to a bool

Cheers
Manuel

@m_magalhaes said in Getting the State of Modifier Keys (ctrl/cmd, shift, alt):

Regarding the pre-R20 and r20 code i don't have any idea instead that storing bool in a bool (0 or 1) make more sense.
In your code pre-R20 you were sending value > 1 to a bool

I see, I got it all wrong all those years.
My implementation came from reading the examples users posted on the forum (now the legacy forum).
Most uses of modifiers keys were checking inside an if-statement, as such I assumed I could move the checking outside of the if and assign it to a Bool instead, to then check on multiple locations in a function.

Here's an example found in the legacy forum

On 06/09/2005 at 12:55, xxxxxxxx wrote:

Hi

the qualifiers are combined bitwise. So you can check each one by

if( key&QSHIFT; )
{
// shift down
}
if( key&CTRL; )
{
// ctrl down
}
..

Notice the original message is full of typos, but the idea is what it is. Similar solutions have been posted since, all with this same idea ... that's where I got the bad habit from.
Thanks for clarifying the use. Will try to remember it for future plugins.

I'm not sure it's a bad habit or what's the difference. There's maybe type conversion, i don't know.

Or maybe with the code optimization there's no difference at the end.

I just wanted to add my 2 cents to have bool and not value xD

Cheers
Manuel