/[packages]/updates/5/libreoffice/current/SOURCES/0001-Resolves-rhbz-1351224-wayland-grab-related-crashes.patch
ViewVC logotype

Contents of /updates/5/libreoffice/current/SOURCES/0001-Resolves-rhbz-1351224-wayland-grab-related-crashes.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1142835 - (show annotations) (download)
Mon Aug 21 23:46:24 2017 UTC (6 years, 8 months ago) by neoclust
File size: 14062 byte(s)
New version 5.1.5
1 From ef70b6a3b0a2e1cc27c890d4c648bac4f276d6ff Mon Sep 17 00:00:00 2001
2 From: rpmbuild <rpmbuild@fedoraproject.org>
3 Date: Thu, 7 Jul 2016 15:56:54 +0100
4 Subject: [PATCH] Resolves: rhbz#1351224 wayland grab related crashes
5
6 only one popup active at a time. Try and find the right path through the
7 uncanny valley which allows popups to appear, to get all mouse input that
8 happens to them, forward keyboard input to their parents, dismiss when the
9 mouse is clicked outside them and not crash if another popup wants to appear
10 to replace it
11 ---
12 vcl/inc/unx/gtk/gtkframe.hxx | 9 ++-
13 vcl/unx/gtk3/gtk3gtkframe.cxx | 171 +++++++++++++++++++-----------------------
14 2 files changed, 84 insertions(+), 96 deletions(-)
15
16 diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
17 index d5aa627..06f9162 100644
18 --- a/vcl/inc/unx/gtk/gtkframe.hxx
19 +++ b/vcl/inc/unx/gtk/gtkframe.hxx
20 @@ -268,6 +268,8 @@ class GtkSalFrame : public SalFrame
21 #endif
22 #else
23 static gboolean signalExpose( GtkWidget*, GdkEventExpose*, gpointer );
24 + void askForXEmbedFocus( sal_Int32 nTimecode );
25 + void grabKeyboard(bool bGrab);
26 #endif
27 static gboolean signalFocus( GtkWidget*, GdkEventFocus*, gpointer );
28 static gboolean signalMap( GtkWidget*, GdkEvent*, gpointer );
29 @@ -298,7 +300,6 @@ class GtkSalFrame : public SalFrame
30 static GdkNativeWindow findTopLevelSystemWindow( GdkNativeWindow aWindow );
31
32 static int m_nFloats;
33 - static std::vector<GtkWidget*> m_aGrabWidgetsBeforeShowFloat;
34
35 bool isFloatGrabWindow() const
36 {
37 @@ -337,7 +338,6 @@ class GtkSalFrame : public SalFrame
38
39 void setMinMaxSize();
40 void createNewWindow( ::Window aParent, bool bXEmbed, SalX11Screen nXScreen );
41 - void askForXEmbedFocus( sal_Int32 nTimecode );
42
43 void AllocateFrame();
44 void TriggerPaintEvent();
45 @@ -364,7 +364,6 @@ public:
46 // be swallowed
47 bool Dispatch( const XEvent* pEvent );
48 void grabPointer(bool bGrab, bool bOwnerEvents = false);
49 - void grabKeyboard(bool bGrab);
50
51 static GtkSalDisplay* getDisplay();
52 static GdkDisplay* getGdkDisplay();
53 @@ -420,6 +419,10 @@ public:
54 void startDrag(gint nButton, gint nDragOriginX, gint nDragOriginY,
55 GdkDragAction sourceActions, GtkTargetList* pTargetList);
56
57 + void WithDrawn();
58 +
59 + static void closePopup();
60 +
61 #endif
62 virtual ~GtkSalFrame();
63
64 diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
65 index db2c25d..41d4c2e 100644
66 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx
67 +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
68 @@ -106,7 +106,6 @@
69 using namespace com::sun::star;
70
71 int GtkSalFrame::m_nFloats = 0;
72 -std::vector<GtkWidget*> GtkSalFrame::m_aGrabWidgetsBeforeShowFloat;
73
74 #if defined ENABLE_GMENU_INTEGRATION
75 static GDBusConnection* pSessionBus = nullptr;
76 @@ -1297,13 +1296,6 @@ void GtkSalFrame::Init( SystemParentData* pSysData )
77 //FIXME: Handling embedded windows, is going to be fun ...
78 }
79
80 -void GtkSalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode )
81 -{
82 - (void) this; // loplugin:staticmethods
83 - (void)i_nTimeCode;
84 - //FIXME: no askForXEmbedFocus for gtk3 yet
85 -}
86 -
87 void GtkSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle )
88 {
89 if( nStyle != m_nExtStyle && ! isChild() )
90 @@ -1443,30 +1435,26 @@ void GtkSalFrame::Show( bool bVisible, bool bNoActivate )
91 if( ! bNoActivate && (m_nStyle & SalFrameStyleFlags::TOOLWINDOW) )
92 m_bSetFocusOnMap = true;
93
94 - gtk_widget_show( m_pWindow );
95 + if (isFloatGrabWindow() && !getDisplay()->GetCaptureFrame() && m_nFloats == 0)
96 + {
97 + m_pParent->grabPointer(true, true);
98 + gtk_grab_add(m_pParent->getMouseEventWidget());
99 + }
100 +
101 + gtk_widget_show(m_pWindow);
102
103 if( isFloatGrabWindow() )
104 {
105 m_nFloats++;
106 if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 1 )
107 {
108 - GtkWindowGroup *pWindowGroup = gtk_window_get_group(GTK_WINDOW(m_pWindow));
109 - GtkWidget* pGrabWidgetBeforeShowFloat;
110 - while ((pGrabWidgetBeforeShowFloat = gtk_window_group_get_current_grab(pWindowGroup)))
111 - {
112 - m_aGrabWidgetsBeforeShowFloat.push_back(pGrabWidgetBeforeShowFloat);
113 - gtk_grab_remove(pGrabWidgetBeforeShowFloat);
114 - }
115 grabPointer(true, true);
116 - GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this;
117 - pKeyboardFrame->grabKeyboard(true);
118 + gtk_grab_add(getMouseEventWidget());
119 }
120 // #i44068# reset parent's IM context
121 if( m_pParent )
122 m_pParent->EndExtTextInput(EndExtTextInputFlags::NONE);
123 }
124 - if( m_bWindowIsGtkPlug )
125 - askForXEmbedFocus( 0 );
126 }
127 else
128 {
129 @@ -1475,12 +1463,10 @@ void GtkSalFrame::Show( bool bVisible, bool bNoActivate )
130 m_nFloats--;
131 if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 0)
132 {
133 - GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this;
134 - pKeyboardFrame->grabKeyboard(false);
135 + gtk_grab_remove(getMouseEventWidget());
136 grabPointer(false);
137 - for (auto i = m_aGrabWidgetsBeforeShowFloat.rbegin(); i != m_aGrabWidgetsBeforeShowFloat.rend(); ++i)
138 - gtk_grab_add(*i);
139 - m_aGrabWidgetsBeforeShowFloat.clear();
140 + gtk_grab_remove(m_pParent->getMouseEventWidget());
141 + m_pParent->grabPointer(false);
142 }
143 }
144 gtk_widget_hide( m_pWindow );
145 @@ -2085,37 +2071,32 @@ void GtkSalFrame::grabPointer( bool bGrab, bool bOwnerEvents )
146 if (!m_pWindow)
147 return;
148
149 - const int nMask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
150 -
151 - GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay());
152 - GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager);
153 +#if GTK_CHECK_VERSION(3, 19, 2)
154 + GdkSeat* pSeat = gdk_display_get_default_seat(getGdkDisplay());
155 if (bGrab)
156 - gdk_device_grab(pPointer, widget_get_window(getMouseEventWidget()), GDK_OWNERSHIP_NONE, bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, gtk_get_current_event_time());
157 + {
158 + gdk_seat_grab(pSeat, widget_get_window(getMouseEventWidget()), GDK_SEAT_CAPABILITY_ALL_POINTING,
159 + bOwnerEvents, NULL, NULL, NULL, NULL);
160 + }
161 else
162 - gdk_device_ungrab(pPointer, gtk_get_current_event_time());
163 -}
164 -
165 -void GtkSalFrame::grabKeyboard( bool bGrab )
166 -{
167 - static const char* pEnv = getenv("SAL_NO_MOUSEGRABS"); // let's not introduce a special var for this
168 - if (pEnv && *pEnv)
169 - return;
170 -
171 - if (!m_pWindow)
172 - return;
173 + {
174 + gdk_seat_ungrab(pSeat);
175 + }
176 +#else
177 + const int nMask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
178
179 GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay());
180 GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager);
181 - GdkDevice* pKeyboard = gdk_device_get_associated_device(pPointer);
182 if (bGrab)
183 {
184 - gdk_device_grab(pKeyboard, widget_get_window(m_pWindow), GDK_OWNERSHIP_NONE,
185 - true, (GdkEventMask)(GDK_KEY_PRESS | GDK_KEY_RELEASE), nullptr, gtk_get_current_event_time());
186 + gdk_device_grab(pPointer, widget_get_window(getMouseEventWidget()), GDK_OWNERSHIP_NONE,
187 + bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, gtk_get_current_event_time());
188 }
189 else
190 {
191 - gdk_device_ungrab(pKeyboard, gtk_get_current_event_time());
192 + gdk_device_ungrab(pPointer, gtk_get_current_event_time());
193 }
194 +#endif
195 }
196
197 void GtkSalFrame::CaptureMouse( bool bCapture )
198 @@ -2557,6 +2538,22 @@ bool GtkSalFrame::HidePopover(sal_uIntPtr nId)
199 #endif
200 }
201
202 +void GtkSalFrame::WithDrawn()
203 +{
204 + if (isFloatGrabWindow())
205 + closePopup();
206 +}
207 +
208 +void GtkSalFrame::closePopup()
209 +{
210 + if (!m_nFloats)
211 + return;
212 + ImplSVData* pSVData = ImplGetSVData();
213 + if (!pSVData->maWinData.mpFirstFloat)
214 + return;
215 + pSVData->maWinData.mpFirstFloat->EndPopupMode(FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll);
216 +}
217 +
218 gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer frame )
219 {
220 UpdateLastInputEventTime(pEvent->time);
221 @@ -2588,62 +2585,33 @@ gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer
222 aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY;
223 aEvent.mnCode = GetMouseModCode( pEvent->state );
224
225 - bool bClosePopups = false;
226 - if( pEvent->type == GDK_BUTTON_PRESS &&
227 - !(pThis->m_nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION)
228 - )
229 - {
230 - if( m_nFloats > 0 )
231 - {
232 - // close popups if user clicks outside our application
233 - gint x, y;
234 - bClosePopups = (gdk_display_get_window_at_pointer( GtkSalFrame::getGdkDisplay(), &x, &y ) == nullptr);
235 - }
236 - /* #i30306# release implicit pointer grab if no popups are open; else
237 - * Drag cannot grab the pointer and will fail.
238 - */
239 - if( m_nFloats < 1 || bClosePopups )
240 - gdk_display_pointer_ungrab( GtkSalFrame::getGdkDisplay(), GDK_CURRENT_TIME );
241 - }
242 + vcl::DeletionListener aDel( pThis );
243
244 - if( pThis->m_bWindowIsGtkPlug &&
245 - pEvent->type == GDK_BUTTON_PRESS &&
246 - pEvent->button == 1 )
247 + if (pEvent->type == GDK_BUTTON_PRESS && pThis->isFloatGrabWindow())
248 {
249 - pThis->askForXEmbedFocus( pEvent->time );
250 + bool bClosePopups = (pEvent->window != widget_get_window(pThis->getMouseEventWidget()));
251 + if (bClosePopups)
252 + closePopup();
253 }
254
255 // --- RTL --- (mirror mouse pos)
256 if( AllSettings::GetLayoutRTL() )
257 aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX;
258
259 - vcl::DeletionListener aDel( pThis );
260 -
261 - pThis->CallCallback( nEventType, &aEvent );
262 -
263 - if( ! aDel.isDeleted() )
264 + if (!aDel.isDeleted())
265 {
266 - if( bClosePopups )
267 - {
268 - ImplSVData* pSVData = ImplGetSVData();
269 - if ( pSVData->maWinData.mpFirstFloat )
270 - {
271 - static const char* pEnv = getenv( "SAL_FLOATWIN_NOAPPFOCUSCLOSE" );
272 - if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoAppFocusClose) && !(pEnv && *pEnv) )
273 - pSVData->maWinData.mpFirstFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
274 - }
275 - }
276 + pThis->CallCallback( nEventType, &aEvent );
277 + }
278
279 - if( ! aDel.isDeleted() )
280 + if (!aDel.isDeleted())
281 + {
282 + int frame_x = (int)(pEvent->x_root - pEvent->x);
283 + int frame_y = (int)(pEvent->y_root - pEvent->y);
284 + if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY )
285 {
286 - int frame_x = (int)(pEvent->x_root - pEvent->x);
287 - int frame_y = (int)(pEvent->y_root - pEvent->y);
288 - if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY )
289 - {
290 - pThis->maGeometry.nX = frame_x;
291 - pThis->maGeometry.nY = frame_y;
292 - pThis->CallCallback( SALEVENT_MOVE, nullptr );
293 - }
294 + pThis->maGeometry.nX = frame_x;
295 + pThis->maGeometry.nY = frame_y;
296 + pThis->CallCallback( SALEVENT_MOVE, nullptr );
297 }
298 }
299
300 @@ -2787,6 +2755,13 @@ gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer
301
302 GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
303
304 + //If a menu, e.g. font name dropdown, is open, then under wayland moving the
305 + //mouse in the top left corner of the toplevel window in a
306 + //0,0,float-width,float-height area generates motion events which are
307 + //delivered to the dropdown
308 + if (pThis->isFloatGrabWindow() && pEvent->window != widget_get_window(pThis->getMouseEventWidget()))
309 + return true;
310 +
311 SalMouseEvent aEvent;
312 aEvent.mnTime = pEvent->time;
313 aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX;
314 @@ -3027,12 +3002,15 @@ gboolean GtkSalFrame::signalUnmap( GtkWidget*, GdkEvent*, gpointer frame )
315 return false;
316 }
317
318 -gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame )
319 +gboolean GtkSalFrame::signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer frame)
320 {
321 UpdateLastInputEventTime(pEvent->time);
322
323 GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
324
325 + if (pThis->isFloatGrabWindow())
326 + return signalKey(pWidget, pEvent, pThis->m_pParent);
327 +
328 vcl::DeletionListener aDel( pThis );
329
330 if( pThis->m_pIMHandler )
331 @@ -3187,11 +3165,18 @@ gboolean GtkSalFrame::signalWindowState( GtkWidget*, GdkEvent* pEvent, gpointer
332 pThis->TriggerPaintEvent();
333 }
334
335 - if( (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_MAXIMIZED) &&
336 - ! (pThis->m_nState & GDK_WINDOW_STATE_MAXIMIZED) )
337 + if ((pEvent->window_state.new_window_state & GDK_WINDOW_STATE_MAXIMIZED) &&
338 + !(pThis->m_nState & GDK_WINDOW_STATE_MAXIMIZED))
339 {
340 pThis->m_aRestorePosSize = GetPosAndSize(GTK_WINDOW(pThis->m_pWindow));
341 }
342 +
343 + if ((pEvent->window_state.new_window_state & GDK_WINDOW_STATE_WITHDRAWN) &&
344 + !(pThis->m_nState & GDK_WINDOW_STATE_WITHDRAWN))
345 + {
346 + pThis->WithDrawn();
347 + }
348 +
349 pThis->m_nState = pEvent->window_state.new_window_state;
350
351 #if OSL_DEBUG_LEVEL > 1
352 --
353 2.7.4
354

  ViewVC Help
Powered by ViewVC 1.1.30