@@ -56,8 +56,6 @@ struct gc_client_state {
5656 struct wl_surface * keyboard_surface;
5757 struct wl_surface * pointer_surface;
5858 uint32_t keyboard_serial;
59- // custom Ctrl modifier
60- bool keyboard_ctrl;
6159 // repeat state
6260 int32_t keyboard_repeat;
6361 int32_t keyboard_delay;
@@ -212,7 +210,7 @@ class WLGraphicsWindow : public osgViewer::GraphicsWindow {
212210 if (_traits->windowDecoration )
213211 xdg_toplevel_unset_fullscreen (_gw.xdg_toplevel );
214212 else
215- xdg_toplevel_set_fullscreen (_gw.xdg_toplevel , _gw. gc -> output [_traits-> screenNum ]);
213+ xdg_toplevel_set_fullscreen (_gw.xdg_toplevel , NULL ); // allow compositor to select screen
216214 WLGWlog (0 ) << _logname << " full=" << !_traits->windowDecoration << " /screen=" << _traits->screenNum << std::endl;
217215 // bool supportsResize yes, we do, no action.
218216 // bool pbuffer (see above)
@@ -316,7 +314,7 @@ class WLGraphicsWindow : public osgViewer::GraphicsWindow {
316314 if (windowDecoration)
317315 xdg_toplevel_unset_fullscreen (_gw.xdg_toplevel );
318316 else
319- xdg_toplevel_set_fullscreen (_gw.xdg_toplevel , _gw. gc -> output [_traits-> screenNum ]);
317+ xdg_toplevel_set_fullscreen (_gw.xdg_toplevel , NULL ); // allow compositor to select screen
320318 return true ;
321319 }
322320 virtual void grabFocus () {
@@ -498,7 +496,6 @@ class WLWindowingSystemInterface : public osg::GraphicsContext::WindowingSystemI
498496 WLWindowingSystemInterface* obj = (WLWindowingSystemInterface*) data;
499497 obj->_gc .keyboard_surface = surface;
500498 obj->_gc .keyboard_serial = serial;
501- obj->_gc .keyboard_ctrl = false ;
502499 WLGWlog (1 ) << " <keyboard enter: " << surface << " >" << std::endl;
503500 // dump pressed keys
504501 uint32_t * pkey = (uint32_t *)keys->data ;
@@ -544,29 +541,52 @@ class WLWindowingSystemInterface : public osg::GraphicsContext::WindowingSystemI
544541 WLWindowingSystemInterface* obj = (WLWindowingSystemInterface*) data;
545542 // update XKB with modifier state: https://wayland-book.com/seat/keyboard.html
546543 xkb_state_update_mask (obj->_gc .xkb_state , mods_depressed, mods_latched, mods_locked, 0 , 0 , group);
544+ if (auto win = obj->get_window (obj->_gc .keyboard_surface )) {
545+ // adjust currently effective modifiers
546+ auto es = win->getEventQueue ()->getCurrentEventState ();
547+ int emods = es->getModKeyMask ();
548+ if (xkb_state_mod_name_is_active (obj->_gc .xkb_state , XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE))
549+ emods |= osgGA::GUIEventAdapter::ModKeyMask::MODKEY_SHIFT;
550+ else
551+ emods &= ~osgGA::GUIEventAdapter::ModKeyMask::MODKEY_SHIFT;
552+ if (xkb_state_mod_name_is_active (obj->_gc .xkb_state , XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE))
553+ emods |= osgGA::GUIEventAdapter::ModKeyMask::MODKEY_CTRL;
554+ else
555+ emods &= ~osgGA::GUIEventAdapter::ModKeyMask::MODKEY_CTRL;
556+ if (xkb_state_mod_name_is_active (obj->_gc .xkb_state , XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE))
557+ emods |= osgGA::GUIEventAdapter::ModKeyMask::MODKEY_ALT;
558+ else
559+ emods &= ~osgGA::GUIEventAdapter::ModKeyMask::MODKEY_ALT;
560+ es->setModKeyMask (emods);
561+ // push through a harmless key to update modifier state in event system, otherwise the joystick b0rks.. (arrrrgh!!)
562+ win->getEventQueue ()->keyPress (osgGA::GUIEventAdapter::KeySymbol::KEY_Shift_L);
563+ }
547564 WLGWlog (0 ) << " <keymods: " << mods_depressed << ' ,' << mods_latched << ' ,' << mods_locked << ' ,' << group << " >" << std::endl;
548565 }
549566 static void keyboard_key (void * data, wl_keyboard* wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
550567 WLWindowingSystemInterface* obj = (WLWindowingSystemInterface*) data;
551568 // NB: from: https://wayland-book.com/seat/keyboard.html
552569 // "Important: the scancode from this event is the Linux evdev scancode. To translate this to an XKB scancode, you must add 8 to the evdev scancode."
570+ key += 8 ;
571+ // ignore modifier keys..
572+ if (!xkb_key_repeats (obj->_gc .xkb_keymap , key))
573+ return ;
553574 // We also rely on the fact that OSG have used the /same UTF32 symbol codes/ as XKB (or so it appears)
554- xkb_keysym_t sym = xkb_state_key_get_one_sym (obj->_gc .xkb_state , key+8 );
555- // independantly of XKB, we maintain a flag for Ctrl modifier, since the above function ignores it..
556- if (XKB_KEY_Control_L==sym || XKB_KEY_Control_R==sym)
557- obj->_gc .keyboard_ctrl = state ? true : false ;
558- // if Ctrl is in play and we have A-Z, synthesize old ASCII values
559- if (obj->_gc .keyboard_ctrl && sym>=XKB_KEY_a && sym<=XKB_KEY_z) {
575+ xkb_keysym_t sym = xkb_state_key_get_one_sym (obj->_gc .xkb_state , key);
576+ // if Ctrl is in play and we have A-Z, synthesize old ASCII values, as 'get_one_sym' above does not translate Ctrl codes..
577+ if (xkb_state_mod_name_is_active (obj->_gc .xkb_state , XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE)
578+ && sym>=XKB_KEY_a && sym<=XKB_KEY_z) {
560579 sym = 1 + (sym - XKB_KEY_a);
561580 }
581+ // find the target window..
562582 if (auto win = obj->get_window (obj->_gc .keyboard_surface )) {
563583 if (state)
564584 win->getEventQueue ()->keyPress ((int )sym);
565585 else
566586 win->getEventQueue ()->keyRelease ((int )sym);
567587 WLGWlog (0 ) << (state?" <keypress: " :" <keyrelease: " ) << key << " =>" << sym << " >" << std::endl;
568588 }
569- // any new keypress always puts us in DELAY state for repeats, releasing any key stops repeats
589+ // any keypress always puts us in DELAY state for repeats, any release and we stop repeating
570590 obj->_gc .keyboard_state = state ? KEYBOARD_DELAY : KEYBOARD_IDLE;
571591 obj->_gc .keyboard_last = (int )sym;
572592 }
0 commit comments