gtk3: New Folder dialog from Templates dialog doesn't get keyboard focus
ctrl+shift+N, and click new folder, no keyboard input is accepted. The dialogs don't get keyboard events, because the keyboard events go to the top level window because of... commit011ce226e8
Author: Caolán McNamara <caolanm@redhat.com> Date: Tue Jan 19 13:22:10 2016 +0000 Resolves: tdf#99604 ungrab modal dialogs (should be tdf#96604) which stripped away the grab from the sub dialog but I did that because menu dropdowns from comboboxes inside modal dialogs didn't receive mouse focus otherwise. I had set our "modal" dialogs to be truly modal and triggering that problem with commit8d5822983e
Author: Caolán McNamara <caolanm@redhat.com> Date: Mon Dec 14 11:36:50 2015 +0000 Related: rhbz#1290014 gtk3: use gtk_window_set_modal on modal dialogs which makes modal dialogs (which are most of them) place correctly under wayland. Modeless ones are still uselessly shoved far to the left, but this makes things near usable and gives the same "graying into the bg" effect for the main window as other gtk apps which I still contend is "a good thing" if we stop removing the grab from the modal dialog, then we need to grab the keyboard and mouse on to the menu on showing those. This then runs into the problem that sometimes we want the keyboard to go to one window and the mouse to go to another, i.e. mouse to the floating menu and the keypresses to its parent combobox. Which was the joy of... commit27e0fee7da
Author: Caolán McNamara <caolanm@redhat.com> Date: Fri Mar 27 15:28:28 2015 +0000 gnome#745909 grab/ungrab keyboard for menus and subsequent fix of commit57ec66e294
Author: Caolán McNamara <caolanm@redhat.com> Date: Thu Jul 23 09:55:01 2015 +0100 Resolves: tdf#92689 grab keyboard focus to parent, not to earlier generations so... lets drop the ungrab on modal dialog attempt and leave that alone. That means that the keyboard focus travels around the modal dialogs stack correctly. For the mouse and keyboard events in menu problems, instead gtk_grab_add on the menu itself, and convert the separate grab of keyboard and mouse to different places with a single grab of everything to the menu, and in the keyInput of such menus where the keyInput would have gone to their parent in the past, forward it on ourselves directly. Using the gtk_grab_add makes the bOwnerEvents mode of mouse grabbing not work correctly anymore. So throw my hat at it, and instead use the simpler mouse grabbing where all events go to the menu, and doesn't send the events outside of it to the parent, the side effect is that now clicking outside the menu doesn't make it go away automatically because its the parent window which used to do that. So instead of dismissing the menu within the gtk plugin when the button click is outside the application, take it onto ourselves to dismiss the menu when the button click is outside the menu. and ditch some metacity hack around thing at this point too I hate this crap Change-Id: If10e758585f156b33680b8d40355302cc1ae72f3
This commit is contained in:
@@ -271,6 +271,7 @@ class GtkSalFrame : public SalFrame
|
||||
static void gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame);
|
||||
static void gestureLongPress(GtkGestureLongPress* gesture, gpointer frame);
|
||||
#endif
|
||||
gboolean handleKey(GtkWidget* pWidget, GdkEventKey* pEvent);
|
||||
#else
|
||||
static gboolean signalExpose( GtkWidget*, GdkEventExpose*, gpointer );
|
||||
#endif
|
||||
|
@@ -1424,21 +1424,6 @@ void GtkSalFrame::Show( bool bVisible, bool bNoActivate )
|
||||
SetDefaultSize();
|
||||
setMinMaxSize();
|
||||
|
||||
if( isFloatGrabWindow() &&
|
||||
m_pParent &&
|
||||
m_nFloats == 0 &&
|
||||
! getDisplay()->GetCaptureFrame() )
|
||||
{
|
||||
/* #i63086#
|
||||
* outsmart Metacity's "focus:mouse" mode
|
||||
* which insists on taking the focus from the document
|
||||
* to the new float. Grab focus to parent frame BEFORE
|
||||
* showing the float (cannot grab it to the float
|
||||
* before show).
|
||||
*/
|
||||
m_pParent->grabPointer( true, true );
|
||||
}
|
||||
|
||||
if( ! bNoActivate && (m_nStyle & SalFrameStyleFlags::TOOLWINDOW) )
|
||||
m_bSetFocusOnMap = true;
|
||||
|
||||
@@ -1449,9 +1434,9 @@ void GtkSalFrame::Show( bool bVisible, bool bNoActivate )
|
||||
m_nFloats++;
|
||||
if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 1 )
|
||||
{
|
||||
grabPointer(true, true);
|
||||
GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this;
|
||||
pKeyboardFrame->grabKeyboard(true);
|
||||
gtk_grab_add(getMouseEventWidget());
|
||||
grabPointer(true);
|
||||
grabKeyboard(true);
|
||||
}
|
||||
// #i44068# reset parent's IM context
|
||||
if( m_pParent )
|
||||
@@ -1467,9 +1452,9 @@ void GtkSalFrame::Show( bool bVisible, bool bNoActivate )
|
||||
m_nFloats--;
|
||||
if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 0)
|
||||
{
|
||||
GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this;
|
||||
pKeyboardFrame->grabKeyboard(false);
|
||||
grabKeyboard(false);
|
||||
grabPointer(false);
|
||||
gtk_grab_remove(getMouseEventWidget());
|
||||
}
|
||||
}
|
||||
gtk_widget_hide( m_pWindow );
|
||||
@@ -2076,9 +2061,13 @@ void GtkSalFrame::grabPointer( bool bGrab, bool bOwnerEvents )
|
||||
GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay());
|
||||
GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager);
|
||||
if (bGrab)
|
||||
{
|
||||
gdk_device_grab(pPointer, widget_get_window(getMouseEventWidget()), GDK_OWNERSHIP_NONE, bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, gtk_get_current_event_time());
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_device_ungrab(pPointer, gtk_get_current_event_time());
|
||||
}
|
||||
}
|
||||
|
||||
void GtkSalFrame::grabKeyboard( bool bGrab )
|
||||
@@ -2414,13 +2403,6 @@ void GtkSalFrame::SetModal(bool bModal)
|
||||
if (!m_pWindow)
|
||||
return;
|
||||
gtk_window_set_modal(GTK_WINDOW(m_pWindow), bModal);
|
||||
if (bModal)
|
||||
{
|
||||
//gtk_window_set_modal bTrue adds a grab, so ungrab here. Quite
|
||||
//possibly we should alternatively call grab_add grab_ungrab on
|
||||
//show/hide of menus ?
|
||||
gtk_grab_remove(m_pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean GtkSalFrame::signalTooltipQuery(GtkWidget*, gint /*x*/, gint /*y*/,
|
||||
@@ -2600,9 +2582,12 @@ gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer
|
||||
{
|
||||
if( m_nFloats > 0 )
|
||||
{
|
||||
// close popups if user clicks outside our application
|
||||
gint x, y;
|
||||
bClosePopups = (gdk_display_get_window_at_pointer( GtkSalFrame::getGdkDisplay(), &x, &y ) == nullptr);
|
||||
// close popups if user clicks outside our menu
|
||||
if (aEvent.mnX < 0 || aEvent.mnY < 0 ||
|
||||
aEvent.mnX > (long)pThis->maGeometry.nWidth || aEvent.mnY > (long)pThis->maGeometry.nHeight)
|
||||
{
|
||||
bClosePopups = true;
|
||||
}
|
||||
}
|
||||
/* #i30306# release implicit pointer grab if no popups are open; else
|
||||
* Drag cannot grab the pointer and will fail.
|
||||
@@ -2795,7 +2780,7 @@ gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer
|
||||
// ask for the next hint
|
||||
gint x, y;
|
||||
GdkModifierType mask;
|
||||
gdk_window_get_pointer( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &x, &y, &mask );
|
||||
gdk_window_get_pointer( widget_get_window(GTK_WIDGET(pThis->getMouseEventWidget())), &x, &y, &mask );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2977,15 +2962,28 @@ gboolean GtkSalFrame::signalUnmap( GtkWidget*, GdkEvent*, gpointer frame )
|
||||
return false;
|
||||
}
|
||||
|
||||
gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame )
|
||||
gboolean GtkSalFrame::signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer frame)
|
||||
{
|
||||
GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
|
||||
return pThis->handleKey(pWidget, pEvent);
|
||||
}
|
||||
|
||||
vcl::DeletionListener aDel( pThis );
|
||||
|
||||
if( pThis->m_pIMHandler )
|
||||
gboolean GtkSalFrame::handleKey(GtkWidget* pWidget, GdkEventKey* pEvent)
|
||||
{
|
||||
//If we're the type of menu that wants to forward keypresses to our parent
|
||||
//widget, do that here, this is related to the gtk_grab_add use in
|
||||
//GtkSalFrame::Show where we want the mouse events to go to us, but
|
||||
//the keyboard events to go to our parent
|
||||
if (isFloatGrabWindow() && !getDisplay()->GetCaptureFrame() && m_nFloats == 1 && m_pParent)
|
||||
{
|
||||
if( pThis->m_pIMHandler->handleKeyEvent( pEvent ) )
|
||||
return m_pParent->handleKey(pWidget, pEvent);
|
||||
}
|
||||
|
||||
vcl::DeletionListener aDel(this);
|
||||
|
||||
if( m_pIMHandler )
|
||||
{
|
||||
if( m_pIMHandler->handleKeyEvent( pEvent ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3001,13 +2999,13 @@ gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame
|
||||
sal_uInt16 nModCode = GetKeyModCode( pEvent->state );
|
||||
|
||||
aModEvt.mnModKeyCode = 0; // emit no MODKEYCHANGE events
|
||||
if( pEvent->type == GDK_KEY_PRESS && !pThis->m_nKeyModifiers )
|
||||
pThis->m_bSendModChangeOnRelease = true;
|
||||
if( pEvent->type == GDK_KEY_PRESS && !m_nKeyModifiers )
|
||||
m_bSendModChangeOnRelease = true;
|
||||
|
||||
else if( pEvent->type == GDK_KEY_RELEASE &&
|
||||
pThis->m_bSendModChangeOnRelease )
|
||||
m_bSendModChangeOnRelease )
|
||||
{
|
||||
aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
|
||||
aModEvt.mnModKeyCode = m_nKeyModifiers;
|
||||
}
|
||||
|
||||
sal_uInt16 nExtModMask = 0;
|
||||
@@ -3058,37 +3056,37 @@ gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame
|
||||
if( pEvent->type == GDK_KEY_RELEASE )
|
||||
{
|
||||
nModCode &= ~nModMask;
|
||||
pThis->m_nKeyModifiers &= ~nExtModMask;
|
||||
m_nKeyModifiers &= ~nExtModMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
nModCode |= nModMask;
|
||||
pThis->m_nKeyModifiers |= nExtModMask;
|
||||
m_nKeyModifiers |= nExtModMask;
|
||||
}
|
||||
|
||||
aModEvt.mnCode = nModCode;
|
||||
aModEvt.mnTime = pEvent->time;
|
||||
aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
|
||||
aModEvt.mnModKeyCode = m_nKeyModifiers;
|
||||
|
||||
pThis->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt );
|
||||
CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
pThis->doKeyCallback( pEvent->state,
|
||||
pEvent->keyval,
|
||||
pEvent->hardware_keycode,
|
||||
pEvent->group,
|
||||
pEvent->time,
|
||||
sal_Unicode(gdk_keyval_to_unicode( pEvent->keyval )),
|
||||
(pEvent->type == GDK_KEY_PRESS),
|
||||
false );
|
||||
doKeyCallback( pEvent->state,
|
||||
pEvent->keyval,
|
||||
pEvent->hardware_keycode,
|
||||
pEvent->group,
|
||||
pEvent->time,
|
||||
sal_Unicode(gdk_keyval_to_unicode( pEvent->keyval )),
|
||||
(pEvent->type == GDK_KEY_PRESS),
|
||||
false );
|
||||
if( ! aDel.isDeleted() )
|
||||
pThis->m_bSendModChangeOnRelease = false;
|
||||
m_bSendModChangeOnRelease = false;
|
||||
}
|
||||
|
||||
if( !aDel.isDeleted() && pThis->m_pIMHandler )
|
||||
pThis->m_pIMHandler->updateIMSpotLocation();
|
||||
if( !aDel.isDeleted() && m_pIMHandler )
|
||||
m_pIMHandler->updateIMSpotLocation();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
Reference in New Issue
Block a user