COpenGLView keyboard events

Hi!

I’m working with the COpenGLView, and it works great so far, except two things.

KEYBOARD HANDLING

One is the keyboard handling: I cannot really get keyboard input to work.

In the vstgui editor I have “mouse-enabled” and “wants-focus” ticked. My abbreviated code is:

class MyOpenglView : public COpenGLView, public IKeyboardHook{
    MyOpenglView(const CRect& size) : COpenGLView(size) {
        ...
        setWantsFocus(true); // redundant?
    }
    
    bool attached(CView* parent){
        if (COpenGLView::attached(parent))
        {
            getFrame()->registerKeyboardHook(this);
            ...
        }
    }
    
    
    // this works
    void onMouseDownEvent(MouseDownEvent& event){
        printf("mouse pressed\n"); 
    }
    
    // this doesn't
    void onKeyboardEvent (KeyboardEvent& event){
        printf("key pressed (direct)\n");
    }
    
    // this works, but only if any other vstgui control has the focus, e.g. a slider
    void onKeyboardEvent (KeyboardEvent& event, CFrame* frame){
        printf("key pressed (global hook)\n");
    }
}

Am I doing anything obviously wrong?


I’m on mac os, and I did dive down the rabbit hole a bit further than I should.
Feel free to ignore this section, but this is the point where I decided I’ll ask for help :slight_smile:

I noticed that when I click the GL view, then an instance of the Objective-C class SMTGCocoa1705414896_CocoaView has the focus. This seems to prevent onActivate(true) from being called. So for example when I move the window out of and then into focus, I observe these steps:

  1. VSTGUI_NSView::windowKeyStateChanged gets called
  2. the firstResponder is SMTGCocoa1705414896_CocoaView. Is this the native view corresponding to the COpenGLView instance?
  3. That view is not a child of the VSTGUI_NSView, as such frame->platformOnActivate(true) never gets called
  4. Any attempt at frame->setFocusView() won’t work, because frame->active is false.
  5. The rest (no keyboard input) seems to fall into place from there.

GL Context creation

My second issue is that every instance of COpenGLView has it’s own context, preventing resource sharing. I patched vstgui for my own purpose; it’s only a few lines of changes for the osx and windows implementations to reuse the same context over and over.

Is there any interest in this? Happy to share my changes, but as far as I can tell from other forum entries COpenGLView is frozen because of Apple’s GL deprecation.

Hi, the OpenGL stuff is indeed deprecated. But it seems someone had the same issue and solved it, see Fixed key event handling for OpenGL views on macOS by 1ci · Pull Request #307 · steinbergmedia/vstgui · GitHub

Maybe this helps.
Cheers,
Arne

1 Like

yes, that’s the same issue. thanks for pointing me to the right place.

from the looks of it the isolated changes to cocoaopenglview.mm will fix my issue, the rest is bonus.

i have a tiny follow up question.

in the current public vstgui release, as well as in the patch from PR307 there’s a tiny snippet of code that seems wrong:

if (modifiers & MacEventModifier::CommandKeyMask)
	event.modifiers.add (ModifierKey::Control);
if (modifiers & MacEventModifier::AlternateKeyMask)
	event.modifiers.add (ModifierKey::Alt);
if (modifiers & MacEventModifier::ControlKeyMask)
	event.modifiers.add (ModifierKey::Super);

so CommandKeyMask => ModifierKey::Control,
and ControlKeyMask => ModifierKey::Super

it seems to be that it should be mapped exactly the other way around.


ps. ok, i found this definition in vstgui:

/** the control key (Command key on macOS and control key on other platforms) */
Control = 1 << 2,
/** the super key (Control key on macOS, Windows key on Windows and Super key on other
   platforms)*/
Super = 1 << 3,

this comment in vstgui/events.h seems to be the culprit.

as a mac user since over a decade: in reality control is still control,
and command is super, not the other way around as the comment claims.

Super key (keyboard button) - Wikipedia.

not sure what to suggest, fixing this would break everybodys code :confused:

I suppose you can patch your own version of the SDK…

In my project, I have a piece of CMake logic to download (or use a local copy of) the SDK and I apply a patch automatically on top of it if necessary (I have a folder which mirrors the SDK structure with only what needs to be replaced). It’s open source. You can see at the root of the project there is a folder for 3.7.5 and one for 3.7.8 because there are issues that have not been fixed…

You could do something similar for your own issue.

1 Like

thanks. i’ll take a good look, seems useful!

The purpose of using it this way, is to write cross platform code without need to distinct between the platforms:
For handling the copy command you would write:

if (event.modifier.is (ModifierKey::Control) && event.character == 'c')
  doCopyCommand ();

And this will work for macOS as there it is “Command-C” and it will work on Windows/Linux as the command there is “Control-C”.

1 Like

that’s what i assumed, but it’s still confusing.

i often see this solved by introducing an action key, along the lines of:

// somewhere in vstgui.h
namespace vstgui{
    // ....
    
    #ifdef __APPLE__
    const ModifierKey ACTION_KEY = ModifierKey::Super;
    #else
    const ModifierKey ACTION_KEY = ModifierKey::Control;
    #endif 
}



// and then check against that
if (event.modifier.is (VSTGUI::ACTION_KEY) && event.character == 'c')
    doCopyCommand ();

this also let’s you write cross platform code, but as someone who is mainly on macos and only sporadically on windows, it feels a bit off to check for “super+a” when i want to know if “ctrl+a” was pressed.

to stick with this example: ctrl+a jumps to the beginning of a line in macos.
on windows windows key + a doesn’t have that behavior, so there’s some sortof of ifdef either way to handle text shortcuts between OSs.

do i rightfully assume that this is a “won’t fix” type of bug either way, because it has too large implications to make such a change now?

I think so, yes.

1 Like