File: | home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx |
Warning: | line 2390, column 9 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * This file is part of the LibreOffice project. | |||
4 | * | |||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | |||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |||
8 | * | |||
9 | * This file incorporates work covered by the following license notice: | |||
10 | * | |||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | |||
12 | * contributor license agreements. See the NOTICE file distributed | |||
13 | * with this work for additional information regarding copyright | |||
14 | * ownership. The ASF licenses this file to you under the Apache | |||
15 | * License, Version 2.0 (the "License"); you may not use this file | |||
16 | * except in compliance with the License. You may obtain a copy of | |||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | |||
18 | */ | |||
19 | ||||
20 | #include <string.h> | |||
21 | #include <string_view> | |||
22 | #include <stdio.h> | |||
23 | #include <stdlib.h> | |||
24 | ||||
25 | #include <tools/debug.hxx> | |||
26 | ||||
27 | #include <vcl/event.hxx> | |||
28 | #include <vcl/floatwin.hxx> | |||
29 | #include <vcl/keycodes.hxx> | |||
30 | #include <vcl/settings.hxx> | |||
31 | #include <vcl/bitmapaccess.hxx> | |||
32 | #include <vcl/opengl/OpenGLContext.hxx> | |||
33 | #include <vcl/BitmapTools.hxx> | |||
34 | ||||
35 | #include <X11/Xlib.h> | |||
36 | #include <X11/Xutil.h> | |||
37 | #include <X11/Xatom.h> | |||
38 | #include <X11/keysym.h> | |||
39 | #include <X11/extensions/shape.h> | |||
40 | ||||
41 | #include <saldatabasic.hxx> | |||
42 | #include <unx/saldisp.hxx> | |||
43 | #include <unx/salgdi.h> | |||
44 | #include <unx/salframe.h> | |||
45 | #include <unx/wmadaptor.hxx> | |||
46 | #include <unx/salbmp.h> | |||
47 | #include <unx/i18n_ic.hxx> | |||
48 | #include <unx/i18n_keysym.hxx> | |||
49 | #include <opengl/zone.hxx> | |||
50 | ||||
51 | #include <unx/gensys.h> | |||
52 | #include <window.h> | |||
53 | ||||
54 | #include <sal/macros.h> | |||
55 | #include <sal/log.hxx> | |||
56 | #include <com/sun/star/uno/Exception.hpp> | |||
57 | ||||
58 | #include <svdata.hxx> | |||
59 | #include <bitmaps.hlst> | |||
60 | ||||
61 | #include <optional> | |||
62 | ||||
63 | #include <algorithm> | |||
64 | ||||
65 | #ifndef Button66 | |||
66 | # define Button66 6 | |||
67 | #endif | |||
68 | #ifndef Button77 | |||
69 | # define Button77 7 | |||
70 | #endif | |||
71 | ||||
72 | using namespace vcl_sal; | |||
73 | ||||
74 | constexpr auto CLIENT_EVENTS = StructureNotifyMask(1L<<17) | |||
75 | | SubstructureNotifyMask(1L<<19) | |||
76 | | KeyPressMask(1L<<0) | |||
77 | | KeyReleaseMask(1L<<1) | |||
78 | | ButtonPressMask(1L<<2) | |||
79 | | ButtonReleaseMask(1L<<3) | |||
80 | | PointerMotionMask(1L<<6) | |||
81 | | EnterWindowMask(1L<<4) | |||
82 | | LeaveWindowMask(1L<<5) | |||
83 | | FocusChangeMask(1L<<21) | |||
84 | | ExposureMask(1L<<15) | |||
85 | | VisibilityChangeMask(1L<<16) | |||
86 | | PropertyChangeMask(1L<<22) | |||
87 | | ColormapChangeMask(1L<<23); | |||
88 | ||||
89 | static ::Window hPresentationWindow = None0L, hPresFocusWindow = None0L; | |||
90 | static ::std::list< ::Window > aPresentationReparentList; | |||
91 | static int nVisibleFloats = 0; | |||
92 | ||||
93 | static void doReparentPresentationDialogues( SalDisplay const * pDisplay ) | |||
94 | { | |||
95 | GetGenericUnixSalData()->ErrorTrapPush(); | |||
96 | for (auto const& elem : aPresentationReparentList) | |||
97 | { | |||
98 | int x, y; | |||
99 | ::Window aRoot, aChild; | |||
100 | unsigned int w, h, bw, d; | |||
101 | XGetGeometry( pDisplay->GetDisplay(), | |||
102 | elem, | |||
103 | &aRoot, | |||
104 | &x, &y, &w, &h, &bw, &d ); | |||
105 | XTranslateCoordinates( pDisplay->GetDisplay(), | |||
106 | hPresentationWindow, | |||
107 | aRoot, | |||
108 | x, y, | |||
109 | &x, &y, | |||
110 | &aChild ); | |||
111 | XReparentWindow( pDisplay->GetDisplay(), | |||
112 | elem, | |||
113 | aRoot, | |||
114 | x, y ); | |||
115 | } | |||
116 | aPresentationReparentList.clear(); | |||
117 | if( hPresFocusWindow ) | |||
118 | XSetInputFocus( pDisplay->GetDisplay(), hPresFocusWindow, PointerRoot1L, CurrentTime0L ); | |||
119 | XSync( pDisplay->GetDisplay(), False0 ); | |||
120 | GetGenericUnixSalData()->ErrorTrapPop(); | |||
121 | } | |||
122 | ||||
123 | bool X11SalFrame::IsOverrideRedirect() const | |||
124 | { | |||
125 | return | |||
126 | ((nStyle_ & SalFrameStyleFlags::INTRO) && !pDisplay_->getWMAdaptor()->supportsSplash()) | |||
127 | || | |||
128 | (!( nStyle_ & ~SalFrameStyleFlags::DEFAULT ) && !pDisplay_->getWMAdaptor()->supportsFullScreen()) | |||
129 | ; | |||
130 | } | |||
131 | ||||
132 | bool X11SalFrame::IsFloatGrabWindow() const | |||
133 | { | |||
134 | static const char* pDisableGrab = getenv( "SAL_DISABLE_FLOATGRAB" ); | |||
135 | ||||
136 | return | |||
137 | ( ( !pDisableGrab || !*pDisableGrab ) && | |||
138 | ( | |||
139 | (nStyle_ & SalFrameStyleFlags::FLOAT) && | |||
140 | ! (nStyle_ & SalFrameStyleFlags::TOOLTIP) && | |||
141 | ! (nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) | |||
142 | ) | |||
143 | ); | |||
144 | } | |||
145 | ||||
146 | void X11SalFrame::setXEmbedInfo() | |||
147 | { | |||
148 | if( !m_bXEmbed ) | |||
149 | return; | |||
150 | ||||
151 | long aInfo[2]; | |||
152 | aInfo[0] = 1; // XEMBED protocol version | |||
153 | aInfo[1] = (bMapped_ ? 1 : 0); // XEMBED_MAPPED | |||
154 | XChangeProperty( pDisplay_->GetDisplay(), | |||
155 | mhWindow, | |||
156 | pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::XEMBED_INFO ), | |||
157 | pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::XEMBED_INFO ), | |||
158 | 32, | |||
159 | PropModeReplace0, | |||
160 | reinterpret_cast<unsigned char*>(aInfo), | |||
161 | SAL_N_ELEMENTS(aInfo)(sizeof(sal_n_array_size(aInfo))) ); | |||
162 | } | |||
163 | ||||
164 | void X11SalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode ) | |||
165 | { | |||
166 | XEvent aEvent; | |||
167 | ||||
168 | memset( &aEvent, 0, sizeof(aEvent) ); | |||
169 | aEvent.xclient.window = mhForeignParent; | |||
170 | aEvent.xclient.type = ClientMessage33; | |||
171 | aEvent.xclient.message_type = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::XEMBED ); | |||
172 | aEvent.xclient.format = 32; | |||
173 | aEvent.xclient.data.l[0] = i_nTimeCode ? i_nTimeCode : CurrentTime0L; | |||
174 | aEvent.xclient.data.l[1] = 3; // XEMBED_REQUEST_FOCUS | |||
175 | aEvent.xclient.data.l[2] = 0; | |||
176 | aEvent.xclient.data.l[3] = 0; | |||
177 | aEvent.xclient.data.l[4] = 0; | |||
178 | ||||
179 | GetGenericUnixSalData()->ErrorTrapPush(); | |||
180 | XSendEvent( pDisplay_->GetDisplay(), | |||
181 | mhForeignParent, | |||
182 | False0, NoEventMask0L, &aEvent ); | |||
183 | XSync( pDisplay_->GetDisplay(), False0 ); | |||
184 | GetGenericUnixSalData()->ErrorTrapPop(); | |||
185 | } | |||
186 | ||||
187 | typedef std::vector< unsigned long > NetWmIconData; | |||
188 | ||||
189 | namespace | |||
190 | { | |||
191 | const std::u16string_view SV_ICON_SIZE48[] = | |||
192 | { | |||
193 | u"" MAINAPP_48_8"res/mainapp_48_8.png", | |||
194 | u"" MAINAPP_48_8"res/mainapp_48_8.png", | |||
195 | u"" ODT_48_8"res/odt_48_8.png", | |||
196 | u"" OTT_48_8"res/ott_48_8.png", | |||
197 | u"" ODS_48_8"res/ods_48_8.png", | |||
198 | u"" OTS_48_8"res/ots_48_8.png", | |||
199 | u"" ODG_48_8"res/odg_48_8.png", | |||
200 | u"" MAINAPP_48_8"res/mainapp_48_8.png", | |||
201 | u"" ODP_48_8"res/odp_48_8.png", | |||
202 | u"" MAINAPP_48_8"res/mainapp_48_8.png", | |||
203 | u"" ODM_48_8"res/odm_48_8.png", | |||
204 | u"" MAINAPP_48_8"res/mainapp_48_8.png", | |||
205 | u"" ODB_48_8"res/odb_48_8.png", | |||
206 | u"" ODF_48_8"res/odf_48_8.png" | |||
207 | }; | |||
208 | ||||
209 | const std::u16string_view SV_ICON_SIZE32[] = | |||
210 | { | |||
211 | u"" MAINAPP_32_8"res/mainapp_32_8.png", | |||
212 | u"" MAINAPP_32_8"res/mainapp_32_8.png", | |||
213 | u"" ODT_32_8"res/odt_32_8.png", | |||
214 | u"" OTT_32_8"res/ott_32_8.png", | |||
215 | u"" ODS_32_8"res/ods_32_8.png", | |||
216 | u"" OTS_32_8"res/ots_32_8.png", | |||
217 | u"" ODG_32_8"res/odg_32_8.png", | |||
218 | u"" MAINAPP_32_8"res/mainapp_32_8.png", | |||
219 | u"" ODP_32_8"res/odp_32_8.png", | |||
220 | u"" MAINAPP_32_8"res/mainapp_32_8.png", | |||
221 | u"" ODM_32_8"res/odm_32_8.png", | |||
222 | u"" MAINAPP_32_8"res/mainapp_32_8.png", | |||
223 | u"" ODB_32_8"res/odb_32_8.png", | |||
224 | u"" ODF_32_8"res/odf_32_8.png" | |||
225 | }; | |||
226 | ||||
227 | const std::u16string_view SV_ICON_SIZE16[] = | |||
228 | { | |||
229 | u"" MAINAPP_16_8"res/mainapp_16_8.png", | |||
230 | u"" MAINAPP_16_8"res/mainapp_16_8.png", | |||
231 | u"" ODT_16_8"res/odt_16_8.png", | |||
232 | u"" OTT_16_8"res/ott_16_8.png", | |||
233 | u"" ODS_16_8"res/ods_16_8.png", | |||
234 | u"" OTS_16_8"res/ots_16_8.png", | |||
235 | u"" ODG_16_8"res/odg_16_8.png", | |||
236 | u"" MAINAPP_16_8"res/mainapp_16_8.png", | |||
237 | u"" ODP_16_8"res/odp_16_8.png", | |||
238 | u"" MAINAPP_16_8"res/mainapp_16_8.png", | |||
239 | u"" ODM_16_8"res/odm_16_8.png", | |||
240 | u"" MAINAPP_16_8"res/mainapp_16_8.png", | |||
241 | u"" ODB_16_8"res/odb_16_8.png", | |||
242 | u"" ODF_16_8"res/odf_16_8.png" | |||
243 | }; | |||
244 | } | |||
245 | ||||
246 | static void CreateNetWmAppIcon( sal_uInt16 nIcon, NetWmIconData& netwm_icon ) | |||
247 | { | |||
248 | const int sizes[ 3 ] = { 48, 32, 16 }; | |||
249 | netwm_icon.resize( 48 * 48 + 32 * 32 + 16 * 16 + 3 * 2 ); | |||
250 | int pos = 0; | |||
251 | for(int size : sizes) | |||
252 | { | |||
253 | OUString sIcon; | |||
254 | if( size >= 48 ) | |||
255 | sIcon = SV_ICON_SIZE48[nIcon]; | |||
256 | else if( size >= 32 ) | |||
257 | sIcon = SV_ICON_SIZE32[nIcon]; | |||
258 | else | |||
259 | sIcon = SV_ICON_SIZE16[nIcon]; | |||
260 | ||||
261 | BitmapEx aIcon = vcl::bitmap::loadFromName(sIcon, ImageLoadFlags::IgnoreScalingFactor); | |||
262 | ||||
263 | if( aIcon.IsEmpty()) | |||
264 | continue; | |||
265 | vcl::bitmap::convertBitmap32To24Plus8(aIcon, aIcon); | |||
266 | Bitmap icon = aIcon.GetBitmap(); | |||
267 | AlphaMask mask; | |||
268 | switch( aIcon.GetTransparentType()) | |||
269 | { | |||
270 | case TransparentType::NONE: | |||
271 | { | |||
272 | sal_uInt8 nTrans = 0; | |||
273 | mask = AlphaMask( icon.GetSizePixel(), &nTrans ); | |||
274 | } | |||
275 | break; | |||
276 | case TransparentType::Color: | |||
277 | mask = AlphaMask( icon.CreateMask( aIcon.GetTransparentColor() ) ); | |||
278 | break; | |||
279 | case TransparentType::Bitmap: | |||
280 | mask = aIcon.GetAlpha(); | |||
281 | break; | |||
282 | } | |||
283 | BitmapReadAccess* iconData = icon.AcquireReadAccess(); | |||
284 | BitmapReadAccess* maskData = mask.AcquireReadAccess(); | |||
285 | netwm_icon[ pos++ ] = size; // width | |||
286 | netwm_icon[ pos++ ] = size; // height | |||
287 | for( int y = 0; y < size; ++y ) | |||
288 | for( int x = 0; x < size; ++x ) | |||
289 | { | |||
290 | BitmapColor col = iconData->GetColor( y, x ); | |||
291 | BitmapColor alpha = maskData->GetColor( y, x ); | |||
292 | netwm_icon[ pos++ ] = (((( 255 - alpha.GetBlue()) * 256U ) + col.GetRed()) * 256 + col.GetGreen()) * 256 + col.GetBlue(); | |||
293 | } | |||
294 | Bitmap::ReleaseAccess( iconData ); | |||
295 | mask.ReleaseAccess( maskData ); | |||
296 | } | |||
297 | netwm_icon.resize( pos ); | |||
298 | } | |||
299 | ||||
300 | static bool lcl_SelectAppIconPixmap( SalDisplay const *pDisplay, SalX11Screen nXScreen, | |||
301 | sal_uInt16 nIcon, sal_uInt16 iconSize, | |||
302 | Pixmap& icon_pixmap, Pixmap& icon_mask, NetWmIconData& netwm_icon) | |||
303 | { | |||
304 | PreDefaultWinNoOpenGLZone aGuard; | |||
305 | ||||
306 | CreateNetWmAppIcon( nIcon, netwm_icon ); | |||
307 | ||||
308 | OUString sIcon; | |||
309 | ||||
310 | if( iconSize >= 48 ) | |||
311 | sIcon = SV_ICON_SIZE48[nIcon]; | |||
312 | else if( iconSize >= 32 ) | |||
313 | sIcon = SV_ICON_SIZE32[nIcon]; | |||
314 | else if( iconSize >= 16 ) | |||
315 | sIcon = SV_ICON_SIZE16[nIcon]; | |||
316 | else | |||
317 | return false; | |||
318 | ||||
319 | BitmapEx aIcon = vcl::bitmap::loadFromName(sIcon, ImageLoadFlags::IgnoreScalingFactor); | |||
320 | ||||
321 | if( aIcon.IsEmpty() ) | |||
322 | return false; | |||
323 | ||||
324 | X11SalBitmap *pBitmap = dynamic_cast < X11SalBitmap * > | |||
325 | (aIcon.ImplGetBitmapSalBitmap().get()); | |||
326 | if (!pBitmap) // FIXME: opengl , TODO SKIA | |||
327 | return false; | |||
328 | ||||
329 | icon_pixmap = XCreatePixmap( pDisplay->GetDisplay(), | |||
330 | pDisplay->GetRootWindow( nXScreen ), | |||
331 | iconSize, iconSize, | |||
332 | DefaultDepth( pDisplay->GetDisplay(),((&((_XPrivDisplay)(pDisplay->GetDisplay()))->screens [nXScreen.getXScreen()])->root_depth) | |||
333 | nXScreen.getXScreen() )((&((_XPrivDisplay)(pDisplay->GetDisplay()))->screens [nXScreen.getXScreen()])->root_depth) | |||
334 | ); | |||
335 | ||||
336 | SalTwoRect aRect(0, 0, iconSize, iconSize, 0, 0, iconSize, iconSize); | |||
337 | ||||
338 | pBitmap->ImplDraw( icon_pixmap, | |||
339 | nXScreen, | |||
340 | DefaultDepth( pDisplay->GetDisplay(),((&((_XPrivDisplay)(pDisplay->GetDisplay()))->screens [nXScreen.getXScreen()])->root_depth) | |||
341 | nXScreen.getXScreen() )((&((_XPrivDisplay)(pDisplay->GetDisplay()))->screens [nXScreen.getXScreen()])->root_depth), | |||
342 | aRect, | |||
343 | DefaultGC( pDisplay->GetDisplay(),((&((_XPrivDisplay)(pDisplay->GetDisplay()))->screens [nXScreen.getXScreen()])->default_gc) | |||
344 | nXScreen.getXScreen() )((&((_XPrivDisplay)(pDisplay->GetDisplay()))->screens [nXScreen.getXScreen()])->default_gc) ); | |||
345 | ||||
346 | icon_mask = None0L; | |||
347 | ||||
348 | if( TransparentType::Bitmap == aIcon.GetTransparentType() ) | |||
349 | { | |||
350 | icon_mask = XCreatePixmap( pDisplay->GetDisplay(), | |||
351 | pDisplay->GetRootWindow( pDisplay->GetDefaultXScreen() ), | |||
352 | iconSize, iconSize, 1); | |||
353 | ||||
354 | XGCValues aValues; | |||
355 | aValues.foreground = 0xffffffff; | |||
356 | aValues.background = 0; | |||
357 | aValues.function = GXcopy0x3; | |||
358 | GC aMonoGC = XCreateGC( pDisplay->GetDisplay(), icon_mask, | |||
359 | GCFunction(1L<<0)|GCForeground(1L<<2)|GCBackground(1L<<3), &aValues ); | |||
360 | ||||
361 | Bitmap aMask = aIcon.GetMask(); | |||
362 | aMask.Invert(); | |||
363 | ||||
364 | X11SalBitmap *pMask = static_cast < X11SalBitmap * > | |||
365 | (aMask.ImplGetSalBitmap().get()); | |||
366 | ||||
367 | pMask->ImplDraw(icon_mask, nXScreen, 1, aRect, aMonoGC); | |||
368 | XFreeGC( pDisplay->GetDisplay(), aMonoGC ); | |||
369 | } | |||
370 | ||||
371 | return true; | |||
372 | } | |||
373 | ||||
374 | void X11SalFrame::Init( SalFrameStyleFlags nSalFrameStyle, SalX11Screen nXScreen, SystemParentData const * pParentData, bool bUseGeometry ) | |||
375 | { | |||
376 | if( nXScreen.getXScreen() >= GetDisplay()->GetXScreenCount() ) | |||
377 | nXScreen = GetDisplay()->GetDefaultXScreen(); | |||
378 | if( mpParent ) | |||
379 | nXScreen = mpParent->m_nXScreen; | |||
380 | ||||
381 | m_nXScreen = nXScreen; | |||
382 | nStyle_ = nSalFrameStyle; | |||
383 | XWMHints Hints; | |||
384 | Hints.flags = InputHint(1L << 0); | |||
385 | Hints.input = (nSalFrameStyle & SalFrameStyleFlags::OWNERDRAWDECORATION) ? False0 : True1; | |||
386 | NetWmIconData netwm_icon; | |||
387 | ||||
388 | int x = 0, y = 0; | |||
389 | unsigned int w = 500, h = 500; | |||
390 | XSetWindowAttributes Attributes; | |||
391 | ||||
392 | int nAttrMask = CWBorderPixel(1L<<3) | |||
393 | | CWBackPixmap(1L<<0) | |||
394 | | CWColormap(1L<<13) | |||
395 | | CWOverrideRedirect(1L<<9) | |||
396 | | CWEventMask(1L<<11) | |||
397 | ; | |||
398 | Attributes.border_pixel = 0; | |||
399 | Attributes.background_pixmap = None0L; | |||
400 | Attributes.colormap = GetDisplay()->GetColormap( m_nXScreen ).GetXColormap(); | |||
401 | Attributes.override_redirect = False0; | |||
402 | Attributes.event_mask = CLIENT_EVENTS; | |||
403 | ||||
404 | const SalVisual& rVis = GetDisplay()->GetVisual( m_nXScreen ); | |||
405 | ::Window aFrameParent = pParentData ? pParentData->aWindow : GetDisplay()->GetRootWindow( m_nXScreen ); | |||
406 | ::Window aClientLeader = None0L; | |||
407 | ||||
408 | if( bUseGeometry ) | |||
409 | { | |||
410 | x = maGeometry.nX; | |||
411 | y = maGeometry.nY; | |||
412 | w = maGeometry.nWidth; | |||
413 | h = maGeometry.nHeight; | |||
414 | } | |||
415 | ||||
416 | if( (nSalFrameStyle & SalFrameStyleFlags::FLOAT) && | |||
417 | ! (nSalFrameStyle & SalFrameStyleFlags::OWNERDRAWDECORATION) | |||
418 | ) | |||
419 | { | |||
420 | if( nShowState_ == SHOWSTATE_UNKNOWN-1 ) | |||
421 | { | |||
422 | w = 10; | |||
423 | h = 10; | |||
424 | } | |||
425 | Attributes.override_redirect = True1; | |||
426 | } | |||
427 | else if( nSalFrameStyle & SalFrameStyleFlags::SYSTEMCHILD ) | |||
428 | { | |||
429 | SAL_WARN_IF( !mpParent, "vcl", "SalFrameStyleFlags::SYSTEMCHILD window without parent" )do { if (true && (!mpParent)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "SalFrameStyleFlags::SYSTEMCHILD window without parent" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "429" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "SalFrameStyleFlags::SYSTEMCHILD window without parent" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SalFrameStyleFlags::SYSTEMCHILD window without parent" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "429" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SalFrameStyleFlags::SYSTEMCHILD window without parent" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "429" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "SalFrameStyleFlags::SYSTEMCHILD window without parent" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SalFrameStyleFlags::SYSTEMCHILD window without parent" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "429" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
430 | if( mpParent ) | |||
431 | { | |||
432 | aFrameParent = mpParent->mhWindow; | |||
433 | // FIXME: since with SalFrameStyleFlags::SYSTEMCHILD | |||
434 | // multiple X11SalFrame objects can have the same shell window | |||
435 | // dispatching events in saldisp.cxx is unclear (the first frame) | |||
436 | // wins. HTH this correctly is unclear yet | |||
437 | // for the time being, treat set the shell window to own window | |||
438 | // like for a normal frame | |||
439 | // mhShellWindow = mpParent->GetShellWindow(); | |||
440 | } | |||
441 | } | |||
442 | else if( pParentData ) | |||
443 | { | |||
444 | // plugin parent may be killed unexpectedly by plugging | |||
445 | // process; start permanently ignoring X errors... | |||
446 | GetGenericUnixSalData()->ErrorTrapPush(); | |||
447 | ||||
448 | nStyle_ |= SalFrameStyleFlags::PLUG; | |||
449 | Attributes.override_redirect = True1; | |||
450 | if( pParentData->nSize >= sizeof(SystemParentData) ) | |||
451 | m_bXEmbed = pParentData->bXEmbedSupport; | |||
452 | ||||
453 | int x_ret, y_ret; | |||
454 | unsigned int bw, d; | |||
455 | ::Window aRoot, aParent; | |||
456 | ||||
457 | XGetGeometry( GetXDisplay(), pParentData->aWindow, | |||
458 | &aRoot, &x_ret, &y_ret, &w, &h, &bw, &d ); | |||
459 | mhForeignParent = pParentData->aWindow; | |||
460 | ||||
461 | mhShellWindow = aParent = mhForeignParent; | |||
462 | ::Window* pChildren; | |||
463 | unsigned int nChildren; | |||
464 | bool bBreak = false; | |||
465 | do | |||
466 | { | |||
467 | XQueryTree( GetDisplay()->GetDisplay(), mhShellWindow, | |||
468 | &aRoot, &aParent, &pChildren, &nChildren ); | |||
469 | XFree( pChildren ); | |||
470 | if( aParent != aRoot ) | |||
471 | mhShellWindow = aParent; | |||
472 | int nCount = 0; | |||
473 | Atom* pProps = XListProperties( GetDisplay()->GetDisplay(), | |||
474 | mhShellWindow, | |||
475 | &nCount ); | |||
476 | for( int i = 0; i < nCount && ! bBreak; ++i ) | |||
477 | bBreak = (pProps[i] == XA_WM_HINTS((Atom) 35)); | |||
478 | if( pProps ) | |||
479 | XFree( pProps ); | |||
480 | } while( aParent != aRoot && ! bBreak ); | |||
481 | ||||
482 | // check if this is really one of our own frames | |||
483 | // do not change the input mask in that case | |||
484 | bool bIsReallyOurFrame = false; | |||
485 | for (auto pSalFrame : GetDisplay()->getFrames() ) | |||
486 | if ( static_cast<const X11SalFrame*>( pSalFrame )->GetWindow() == mhForeignParent ) | |||
487 | { | |||
488 | bIsReallyOurFrame = true; | |||
489 | break; | |||
490 | } | |||
491 | if (!bIsReallyOurFrame) | |||
492 | { | |||
493 | XSelectInput( GetDisplay()->GetDisplay(), mhForeignParent, StructureNotifyMask(1L<<17) | FocusChangeMask(1L<<21) ); | |||
494 | XSelectInput( GetDisplay()->GetDisplay(), mhShellWindow, StructureNotifyMask(1L<<17) | FocusChangeMask(1L<<21) ); | |||
495 | } | |||
496 | } | |||
497 | else | |||
498 | { | |||
499 | if( ! bUseGeometry ) | |||
500 | { | |||
501 | Size aScreenSize( GetDisplay()->getDataForScreen( m_nXScreen ).m_aSize ); | |||
502 | w = aScreenSize.Width(); | |||
503 | h = aScreenSize.Height(); | |||
504 | if( nSalFrameStyle & SalFrameStyleFlags::SIZEABLE && | |||
505 | nSalFrameStyle & SalFrameStyleFlags::MOVEABLE ) | |||
506 | { | |||
507 | Size aBestFitSize(bestmaxFrameSizeForScreenSize(aScreenSize)); | |||
508 | w = aBestFitSize.Width(); | |||
509 | h = aBestFitSize.Height(); | |||
510 | } | |||
511 | if( ! mpParent ) | |||
512 | { | |||
513 | // find the last document window (if any) | |||
514 | const X11SalFrame* pFrame = nullptr; | |||
515 | bool bIsDocumentWindow = false; | |||
516 | for (auto pSalFrame : GetDisplay()->getFrames() ) | |||
517 | { | |||
518 | pFrame = static_cast< const X11SalFrame* >( pSalFrame ); | |||
519 | if( !pFrame->mpParent | |||
520 | && !pFrame->mbFullScreen | |||
521 | && ( pFrame->nStyle_ & SalFrameStyleFlags::SIZEABLE ) | |||
522 | && pFrame->GetUnmirroredGeometry().nWidth | |||
523 | && pFrame->GetUnmirroredGeometry().nHeight ) | |||
524 | { | |||
525 | bIsDocumentWindow = true; | |||
526 | break; | |||
527 | } | |||
528 | } | |||
529 | ||||
530 | if( bIsDocumentWindow ) | |||
531 | { | |||
532 | // set a document position and size | |||
533 | // the first frame gets positioned by the window manager | |||
534 | const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() ); | |||
535 | x = rGeom.nX; | |||
536 | y = rGeom.nY; | |||
537 | if( x+static_cast<int>(w)+40 <= static_cast<int>(aScreenSize.Width()) && | |||
538 | y+static_cast<int>(h)+40 <= static_cast<int>(aScreenSize.Height()) | |||
539 | ) | |||
540 | { | |||
541 | y += 40; | |||
542 | x += 40; | |||
543 | } | |||
544 | else | |||
545 | { | |||
546 | x = 10; // leave some space for decoration | |||
547 | y = 20; | |||
548 | } | |||
549 | } | |||
550 | else if( GetDisplay()->IsXinerama() ) | |||
551 | { | |||
552 | // place frame on same screen as mouse pointer | |||
553 | ::Window aRoot, aChild; | |||
554 | int root_x = 0, root_y = 0, lx, ly; | |||
555 | unsigned int mask; | |||
556 | XQueryPointer( GetXDisplay(), | |||
557 | GetDisplay()->GetRootWindow( m_nXScreen ), | |||
558 | &aRoot, &aChild, | |||
559 | &root_x, &root_y, &lx, &ly, &mask ); | |||
560 | const std::vector< tools::Rectangle >& rScreens = GetDisplay()->GetXineramaScreens(); | |||
561 | for(const auto & rScreen : rScreens) | |||
562 | if( rScreen.IsInside( Point( root_x, root_y ) ) ) | |||
563 | { | |||
564 | x = rScreen.Left(); | |||
565 | y = rScreen.Top(); | |||
566 | break; | |||
567 | } | |||
568 | } | |||
569 | } | |||
570 | } | |||
571 | Attributes.win_gravity = pDisplay_->getWMAdaptor()->getInitWinGravity(); | |||
572 | nAttrMask |= CWWinGravity(1L<<5); | |||
573 | if( mpParent ) | |||
574 | { | |||
575 | Attributes.save_under = True1; | |||
576 | nAttrMask |= CWSaveUnder(1L<<10); | |||
577 | } | |||
578 | if( IsOverrideRedirect() ) | |||
579 | Attributes.override_redirect = True1; | |||
580 | // default icon | |||
581 | if( !(nStyle_ & SalFrameStyleFlags::INTRO) ) | |||
582 | { | |||
583 | bool bOk=false; | |||
584 | try | |||
585 | { | |||
586 | bOk = lcl_SelectAppIconPixmap( pDisplay_, m_nXScreen, | |||
587 | mnIconID != SV_ICON_ID_OFFICE1 ? mnIconID : | |||
588 | (mpParent ? mpParent->mnIconID : SV_ICON_ID_OFFICE1), 32, | |||
589 | Hints.icon_pixmap, Hints.icon_mask, netwm_icon ); | |||
590 | } | |||
591 | catch( css::uno::Exception& ) | |||
592 | { | |||
593 | // can happen - no ucb during early startup | |||
594 | } | |||
595 | if( bOk ) | |||
596 | { | |||
597 | Hints.flags |= IconPixmapHint(1L << 2); | |||
598 | if( Hints.icon_mask ) | |||
599 | Hints.flags |= IconMaskHint(1L << 5); | |||
600 | } | |||
601 | } | |||
602 | ||||
603 | // find the top level frame of the transience hierarchy | |||
604 | X11SalFrame* pFrame = this; | |||
605 | while( pFrame->mpParent ) | |||
606 | pFrame = pFrame->mpParent; | |||
607 | if( pFrame->nStyle_ & SalFrameStyleFlags::PLUG ) | |||
608 | { | |||
609 | // if the top level window is a plugin window, | |||
610 | // then we should place us in the same window group as | |||
611 | // the parent application (or none if there is no window group | |||
612 | // hint in the parent). | |||
613 | if( pFrame->GetShellWindow() ) | |||
614 | { | |||
615 | XWMHints* pWMHints = XGetWMHints( pDisplay_->GetDisplay(), | |||
616 | pFrame->GetShellWindow() ); | |||
617 | if( pWMHints ) | |||
618 | { | |||
619 | if( pWMHints->flags & WindowGroupHint(1L << 6) ) | |||
620 | { | |||
621 | Hints.flags |= WindowGroupHint(1L << 6); | |||
622 | Hints.window_group = pWMHints->window_group; | |||
623 | } | |||
624 | XFree( pWMHints ); | |||
625 | } | |||
626 | } | |||
627 | } | |||
628 | else | |||
629 | { | |||
630 | Hints.flags |= WindowGroupHint(1L << 6); | |||
631 | Hints.window_group = pFrame->GetShellWindow(); | |||
632 | // note: for a normal document window this will produce None | |||
633 | // as the window is not yet created and the shell window is | |||
634 | // initialized to None. This must be corrected after window creation. | |||
635 | aClientLeader = GetDisplay()->GetDrawable( m_nXScreen ); | |||
636 | } | |||
637 | } | |||
638 | ||||
639 | nShowState_ = SHOWSTATE_UNKNOWN-1; | |||
640 | bViewable_ = true; | |||
641 | bMapped_ = false; | |||
642 | nVisibility_ = VisibilityFullyObscured2; | |||
643 | mhWindow = XCreateWindow( GetXDisplay(), | |||
644 | aFrameParent, | |||
645 | x, y, | |||
646 | w, h, | |||
647 | 0, | |||
648 | rVis.GetDepth(), | |||
649 | InputOutput1, | |||
650 | rVis.GetVisual(), | |||
651 | nAttrMask, | |||
652 | &Attributes ); | |||
653 | // FIXME: see above: fake shell window for now to own window | |||
654 | if( pParentData == nullptr ) | |||
655 | { | |||
656 | mhShellWindow = mhWindow; | |||
657 | } | |||
658 | ||||
659 | // correct window group if necessary | |||
660 | if( (Hints.flags & WindowGroupHint(1L << 6)) == WindowGroupHint(1L << 6) ) | |||
661 | { | |||
662 | if( Hints.window_group == None0L ) | |||
663 | Hints.window_group = GetShellWindow(); | |||
664 | } | |||
665 | ||||
666 | maGeometry.nX = x; | |||
667 | maGeometry.nY = y; | |||
668 | maGeometry.nWidth = w; | |||
669 | maGeometry.nHeight = h; | |||
670 | updateScreenNumber(); | |||
671 | ||||
672 | XSync( GetXDisplay(), False0 ); | |||
673 | setXEmbedInfo(); | |||
674 | ||||
675 | Time nUserTime = (nStyle_ & (SalFrameStyleFlags::OWNERDRAWDECORATION | SalFrameStyleFlags::TOOLWINDOW) ) == SalFrameStyleFlags::NONE ? | |||
676 | pDisplay_->GetLastUserEventTime() : 0; | |||
677 | pDisplay_->getWMAdaptor()->setUserTime( this, nUserTime ); | |||
678 | ||||
679 | if( ! pParentData && ! IsChildWindow() && ! Attributes.override_redirect ) | |||
680 | { | |||
681 | XSetWMHints( GetXDisplay(), mhWindow, &Hints ); | |||
682 | // WM Protocols && internals | |||
683 | Atom a[3]; | |||
684 | int n = 0; | |||
685 | a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW ); | |||
686 | ||||
687 | // LibreOffice advertises NET_WM_PING atom, so mutter rightfully warns of an unresponsive application during debugging. | |||
688 | // Hack that out unconditionally for debug builds, as per https://bugzilla.redhat.com/show_bug.cgi?id=981149 | |||
689 | // upstream refuses to make this configurable in any way. | |||
690 | // NOTE: You need to use the 'gen' backend for this to work (SAL_USE_VCLPLUGIN=gen) | |||
691 | #if OSL_DEBUG_LEVEL1 < 1 | |||
692 | if( pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ) ) | |||
693 | a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ); | |||
694 | #endif | |||
695 | ||||
696 | if( nSalFrameStyle & SalFrameStyleFlags::OWNERDRAWDECORATION ) | |||
697 | a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_TAKE_FOCUS ); | |||
698 | XSetWMProtocols( GetXDisplay(), GetShellWindow(), a, n ); | |||
699 | ||||
700 | // force wm class hint | |||
701 | mnExtStyle = ~0; | |||
702 | if (mpParent) | |||
703 | m_sWMClass = mpParent->m_sWMClass; | |||
704 | SetExtendedFrameStyle( 0 ); | |||
705 | ||||
706 | XSizeHints* pHints = XAllocSizeHints(); | |||
707 | pHints->flags = PWinGravity(1L << 9) | PPosition(1L << 2); | |||
708 | pHints->win_gravity = GetDisplay()->getWMAdaptor()->getPositionWinGravity(); | |||
709 | pHints->x = 0; | |||
710 | pHints->y = 0; | |||
711 | if( mbFullScreen ) | |||
712 | { | |||
713 | pHints->flags |= PMaxSize(1L << 5) | PMinSize(1L << 4); | |||
714 | pHints->max_width = w+100; | |||
715 | pHints->max_height = h+100; | |||
716 | pHints->min_width = w; | |||
717 | pHints->min_height = h; | |||
718 | } | |||
719 | XSetWMNormalHints( GetXDisplay(), | |||
720 | GetShellWindow(), | |||
721 | pHints ); | |||
722 | XFree (pHints); | |||
723 | ||||
724 | // set PID and WM_CLIENT_MACHINE | |||
725 | pDisplay_->getWMAdaptor()->setClientMachine( this ); | |||
726 | pDisplay_->getWMAdaptor()->setPID( this ); | |||
727 | ||||
728 | // set client leader | |||
729 | if( aClientLeader ) | |||
730 | { | |||
731 | XChangeProperty( GetXDisplay(), | |||
732 | mhWindow, | |||
733 | pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_CLIENT_LEADER), | |||
734 | XA_WINDOW((Atom) 33), | |||
735 | 32, | |||
736 | PropModeReplace0, | |||
737 | reinterpret_cast<unsigned char*>(&aClientLeader), | |||
738 | 1 | |||
739 | ); | |||
740 | } | |||
741 | #define DECOFLAGS(SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::CLOSEABLE) (SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::CLOSEABLE) | |||
742 | int nDecoFlags = WMAdaptor::decoration_All; | |||
743 | if( (nStyle_ & SalFrameStyleFlags::PARTIAL_FULLSCREEN) || | |||
744 | (nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) | |||
745 | ) | |||
746 | nDecoFlags = 0; | |||
747 | else if( (nStyle_ & DECOFLAGS(SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::CLOSEABLE) ) != DECOFLAGS(SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::CLOSEABLE) || (nStyle_ & SalFrameStyleFlags::TOOLWINDOW) ) | |||
748 | { | |||
749 | if( nStyle_ & DECOFLAGS(SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::CLOSEABLE) ) | |||
750 | // if any decoration, then show a border | |||
751 | nDecoFlags = WMAdaptor::decoration_Border; | |||
752 | else | |||
753 | nDecoFlags = 0; | |||
754 | ||||
755 | if( ! mpParent && (nStyle_ & DECOFLAGS(SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::CLOSEABLE)) ) | |||
756 | // don't add a min button if window should be decorationless | |||
757 | nDecoFlags |= WMAdaptor::decoration_MinimizeBtn; | |||
758 | if( nStyle_ & SalFrameStyleFlags::CLOSEABLE ) | |||
759 | nDecoFlags |= WMAdaptor::decoration_CloseBtn; | |||
760 | if( nStyle_ & SalFrameStyleFlags::SIZEABLE ) | |||
761 | { | |||
762 | nDecoFlags |= WMAdaptor::decoration_Resize; | |||
763 | if( ! (nStyle_ & SalFrameStyleFlags::TOOLWINDOW) ) | |||
764 | nDecoFlags |= WMAdaptor::decoration_MaximizeBtn; | |||
765 | } | |||
766 | if( nStyle_ & SalFrameStyleFlags::MOVEABLE ) | |||
767 | nDecoFlags |= WMAdaptor::decoration_Title; | |||
768 | } | |||
769 | ||||
770 | WMWindowType eType = WMWindowType::Normal; | |||
771 | if( nStyle_ & SalFrameStyleFlags::INTRO ) | |||
772 | eType = WMWindowType::Splash; | |||
773 | if( (nStyle_ & SalFrameStyleFlags::DIALOG) && hPresentationWindow == None0L ) | |||
774 | eType = WMWindowType::ModelessDialogue; | |||
775 | if( nStyle_ & SalFrameStyleFlags::TOOLWINDOW ) | |||
776 | eType = WMWindowType::Utility; | |||
777 | if( nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION ) | |||
778 | eType = WMWindowType::Toolbar; | |||
779 | if( (nStyle_ & SalFrameStyleFlags::PARTIAL_FULLSCREEN) | |||
780 | && GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) | |||
781 | eType = WMWindowType::Dock; | |||
782 | ||||
783 | GetDisplay()->getWMAdaptor()-> | |||
784 | setFrameTypeAndDecoration( this, | |||
785 | eType, | |||
786 | nDecoFlags, | |||
787 | hPresentationWindow ? nullptr : mpParent ); | |||
788 | ||||
789 | if( (nStyle_ & (SalFrameStyleFlags::DEFAULT | | |||
790 | SalFrameStyleFlags::OWNERDRAWDECORATION| | |||
791 | SalFrameStyleFlags::FLOAT | | |||
792 | SalFrameStyleFlags::INTRO | | |||
793 | SalFrameStyleFlags::PARTIAL_FULLSCREEN) ) | |||
794 | == SalFrameStyleFlags::DEFAULT ) | |||
795 | pDisplay_->getWMAdaptor()->maximizeFrame( this ); | |||
796 | ||||
797 | if( !netwm_icon.empty() && GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_ICON )) | |||
798 | XChangeProperty( GetXDisplay(), mhWindow, | |||
799 | GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_ICON ), | |||
800 | XA_CARDINAL((Atom) 6), 32, PropModeReplace0, reinterpret_cast<unsigned char*>(netwm_icon.data()), netwm_icon.size()); | |||
801 | } | |||
802 | ||||
803 | m_nWorkArea = GetDisplay()->getWMAdaptor()->getCurrentWorkArea(); | |||
804 | ||||
805 | // Pointer | |||
806 | SetPointer( PointerStyle::Arrow ); | |||
807 | } | |||
808 | ||||
809 | X11SalFrame::X11SalFrame( SalFrame *pParent, SalFrameStyleFlags nSalFrameStyle, | |||
810 | SystemParentData const * pSystemParent ) : | |||
811 | m_nXScreen( 0 ) | |||
812 | { | |||
813 | GenericUnixSalData *pData = GetGenericUnixSalData(); | |||
814 | ||||
815 | mpParent = static_cast< X11SalFrame* >( pParent ); | |||
816 | ||||
817 | mbTransientForRoot = false; | |||
818 | ||||
819 | pDisplay_ = vcl_sal::getSalDisplay(pData); | |||
820 | // insert frame in framelist | |||
821 | pDisplay_->registerFrame( this ); | |||
822 | ||||
823 | mhWindow = None0L; | |||
824 | mhShellWindow = None0L; | |||
825 | mhStackingWindow = None0L; | |||
826 | mhForeignParent = None0L; | |||
827 | m_bSetFocusOnMap = false; | |||
828 | ||||
829 | pGraphics_ = nullptr; | |||
830 | pFreeGraphics_ = nullptr; | |||
831 | ||||
832 | hCursor_ = None0L; | |||
833 | nCaptured_ = 0; | |||
834 | ||||
835 | mbSendExtKeyModChange = false; | |||
836 | mnExtKeyMod = ModKeyFlags::NONE; | |||
837 | ||||
838 | nShowState_ = SHOWSTATE_UNKNOWN-1; | |||
839 | nWidth_ = 0; | |||
840 | nHeight_ = 0; | |||
841 | nStyle_ = SalFrameStyleFlags::NONE; | |||
842 | mnExtStyle = 0; | |||
843 | bAlwaysOnTop_ = false; | |||
844 | ||||
845 | // set bViewable_ to true: hack GetClientSize to report something | |||
846 | // different to 0/0 before first map | |||
847 | bViewable_ = true; | |||
848 | bMapped_ = false; | |||
849 | bDefaultPosition_ = true; | |||
850 | nVisibility_ = VisibilityFullyObscured2; | |||
851 | m_nWorkArea = 0; | |||
852 | m_bXEmbed = false; | |||
853 | ||||
854 | ||||
855 | mpInputContext = nullptr; | |||
856 | mbInputFocus = False0; | |||
857 | ||||
858 | maAlwaysOnTopRaiseTimer.SetInvokeHandler( LINK( this, X11SalFrame, HandleAlwaysOnTopRaise )::tools::detail::makeLink( ::tools::detail::castTo<X11SalFrame *>(this), &X11SalFrame::LinkStubHandleAlwaysOnTopRaise ) ); | |||
859 | maAlwaysOnTopRaiseTimer.SetTimeout( 100 ); | |||
860 | maAlwaysOnTopRaiseTimer.SetDebugName( "vcl::X11SalFrame maAlwaysOnTopRaiseTimer" ); | |||
861 | ||||
862 | meWindowType = WMWindowType::Normal; | |||
863 | mbMaximizedVert = false; | |||
864 | mbMaximizedHorz = false; | |||
865 | mbShaded = false; | |||
866 | mbFullScreen = false; | |||
867 | ||||
868 | mnIconID = SV_ICON_ID_OFFICE1; | |||
869 | ||||
870 | if( mpParent ) | |||
871 | mpParent->maChildren.push_back( this ); | |||
872 | ||||
873 | Init( nSalFrameStyle, GetDisplay()->GetDefaultXScreen(), pSystemParent ); | |||
874 | } | |||
875 | ||||
876 | X11SalFrame::~X11SalFrame() | |||
877 | { | |||
878 | notifyDelete(); | |||
879 | ||||
880 | m_vClipRectangles.clear(); | |||
881 | ||||
882 | if( mhStackingWindow ) | |||
883 | aPresentationReparentList.remove( mhStackingWindow ); | |||
884 | ||||
885 | // remove from parent's list | |||
886 | if( mpParent ) | |||
887 | mpParent->maChildren.remove( this ); | |||
888 | ||||
889 | // deregister on SalDisplay | |||
890 | pDisplay_->deregisterFrame( this ); | |||
891 | ||||
892 | // unselect all events, some may be still in the queue anyway | |||
893 | if( ! IsSysChildWindow() ) | |||
894 | XSelectInput( GetXDisplay(), GetShellWindow(), 0 ); | |||
895 | XSelectInput( GetXDisplay(), GetWindow(), 0 ); | |||
896 | ||||
897 | ShowFullScreen( false, 0 ); | |||
898 | ||||
899 | if( bMapped_ ) | |||
900 | Show( false ); | |||
901 | ||||
902 | if( mpInputContext ) | |||
903 | { | |||
904 | mpInputContext->UnsetICFocus(); | |||
905 | mpInputContext->Unmap(); | |||
906 | mpInputContext.reset(); | |||
907 | } | |||
908 | ||||
909 | if( GetWindow() == hPresentationWindow ) | |||
910 | { | |||
911 | hPresentationWindow = None0L; | |||
912 | doReparentPresentationDialogues( GetDisplay() ); | |||
913 | } | |||
914 | ||||
915 | if( pGraphics_ ) | |||
916 | { | |||
917 | pGraphics_->DeInit(); | |||
918 | pGraphics_.reset(); | |||
919 | } | |||
920 | ||||
921 | if( pFreeGraphics_ ) | |||
922 | { | |||
923 | pFreeGraphics_->DeInit(); | |||
924 | pFreeGraphics_.reset(); | |||
925 | } | |||
926 | ||||
927 | // reset all OpenGL contexts using this window | |||
928 | rtl::Reference<OpenGLContext> pContext = ImplGetSVData()->maGDIData.mpLastContext; | |||
929 | while( pContext.is() ) | |||
930 | { | |||
931 | if (static_cast<const GLX11Window&>(pContext->getOpenGLWindow()).win == mhWindow) | |||
932 | pContext->reset(); | |||
933 | pContext = pContext->mpPrevContext; | |||
934 | } | |||
935 | ||||
936 | XDestroyWindow( GetXDisplay(), mhWindow ); | |||
937 | } | |||
938 | ||||
939 | void X11SalFrame::SetExtendedFrameStyle( SalExtStyle nStyle ) | |||
940 | { | |||
941 | if( nStyle != mnExtStyle && ! IsChildWindow() ) | |||
942 | { | |||
943 | mnExtStyle = nStyle; | |||
944 | updateWMClass(); | |||
945 | } | |||
946 | } | |||
947 | ||||
948 | const SystemEnvData* X11SalFrame::GetSystemData() const | |||
949 | { | |||
950 | X11SalFrame *pFrame = const_cast<X11SalFrame*>(this); | |||
951 | pFrame->maSystemChildData.pDisplay = GetXDisplay(); | |||
952 | pFrame->maSystemChildData.aWindow = pFrame->GetWindow(); | |||
953 | pFrame->maSystemChildData.pSalFrame = pFrame; | |||
954 | pFrame->maSystemChildData.pWidget = nullptr; | |||
955 | pFrame->maSystemChildData.pVisual = GetDisplay()->GetVisual( m_nXScreen ).GetVisual(); | |||
956 | pFrame->maSystemChildData.nScreen = m_nXScreen.getXScreen(); | |||
957 | pFrame->maSystemChildData.aShellWindow = pFrame->GetShellWindow(); | |||
958 | pFrame->maSystemChildData.toolkit = SystemEnvData::Toolkit::Gen; | |||
959 | pFrame->maSystemChildData.platform = SystemEnvData::Platform::Xcb; | |||
960 | return &maSystemChildData; | |||
961 | } | |||
962 | ||||
963 | SalGraphics *X11SalFrame::AcquireGraphics() | |||
964 | { | |||
965 | if( pGraphics_ ) | |||
966 | return nullptr; | |||
967 | ||||
968 | if( pFreeGraphics_ ) | |||
969 | { | |||
970 | pGraphics_ = std::move(pFreeGraphics_); | |||
971 | } | |||
972 | else | |||
973 | { | |||
974 | pGraphics_.reset(new X11SalGraphics()); | |||
975 | pGraphics_->Init( this, GetWindow(), m_nXScreen ); | |||
976 | } | |||
977 | ||||
978 | return pGraphics_.get(); | |||
979 | } | |||
980 | ||||
981 | void X11SalFrame::ReleaseGraphics( SalGraphics *pGraphics ) | |||
982 | { | |||
983 | SAL_WARN_IF( pGraphics != pGraphics_.get(), "vcl", "SalFrame::ReleaseGraphics pGraphics!=pGraphics_" )do { if (true && (pGraphics != pGraphics_.get())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SalFrame::ReleaseGraphics pGraphics!=pGraphics_" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "983" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "SalFrame::ReleaseGraphics pGraphics!=pGraphics_" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SalFrame::ReleaseGraphics pGraphics!=pGraphics_"; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "983" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SalFrame::ReleaseGraphics pGraphics!=pGraphics_" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "983" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "SalFrame::ReleaseGraphics pGraphics!=pGraphics_" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SalFrame::ReleaseGraphics pGraphics!=pGraphics_"; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "983" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
984 | ||||
985 | if( pGraphics != pGraphics_.get() ) | |||
986 | return; | |||
987 | ||||
988 | pFreeGraphics_ = std::move(pGraphics_); | |||
989 | } | |||
990 | ||||
991 | void X11SalFrame::updateGraphics( bool bClear ) | |||
992 | { | |||
993 | Drawable aDrawable = bClear ? None0L : GetWindow(); | |||
994 | if( pGraphics_ ) | |||
995 | pGraphics_->SetDrawable( aDrawable, nullptr, m_nXScreen ); | |||
996 | if( pFreeGraphics_ ) | |||
997 | pFreeGraphics_->SetDrawable( aDrawable, nullptr, m_nXScreen ); | |||
998 | } | |||
999 | ||||
1000 | void X11SalFrame::SetIcon( sal_uInt16 nIcon ) | |||
1001 | { | |||
1002 | if ( IsChildWindow() ) | |||
1003 | return; | |||
1004 | ||||
1005 | // 0 == default icon -> #1 | |||
1006 | if ( nIcon == 0 ) | |||
1007 | nIcon = 1; | |||
1008 | ||||
1009 | mnIconID = nIcon; | |||
1010 | ||||
1011 | XIconSize *pIconSize = nullptr; | |||
1012 | int nSizes = 0; | |||
1013 | int iconSize = 32; | |||
1014 | if ( XGetIconSizes( GetXDisplay(), GetDisplay()->GetRootWindow( m_nXScreen ), &pIconSize, &nSizes ) ) | |||
1015 | { | |||
1016 | #if OSL_DEBUG_LEVEL1 > 1 | |||
1017 | SAL_INFO("vcl.window", "X11SalFrame::SetIcon(): found "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1018 | << nSizesdo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1019 | << " IconSizes:")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::SetIcon(): found " << nSizes << " IconSizes:"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1019" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1020 | #endif | |||
1021 | int i; | |||
1022 | for( i=0; i<nSizes; i++) | |||
1023 | { | |||
1024 | // select largest supported icon | |||
1025 | if( pIconSize[i].max_width > iconSize ) | |||
1026 | { | |||
1027 | iconSize = pIconSize[i].max_width; | |||
1028 | } | |||
1029 | ||||
1030 | #if OSL_DEBUG_LEVEL1 > 1 | |||
1031 | SAL_INFO("vcl.window", "min: "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "min: " << pIconSize [i].min_width << ", " << pIconSize[i].min_height) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1032 | << pIconSize[i].min_widthdo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "min: " << pIconSize [i].min_width << ", " << pIconSize[i].min_height) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1033 | << ", "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "min: " << pIconSize [i].min_width << ", " << pIconSize[i].min_height) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1034 | << pIconSize[i].min_height)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "min: " << pIconSize [i].min_width << ", " << pIconSize[i].min_height) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "min: " << pIconSize[i].min_width << ", " << pIconSize[i].min_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1034" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1035 | SAL_INFO("vcl.window", "max: "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "max: " << pIconSize [i].max_width << ", " << pIconSize[i].max_height) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1036 | << pIconSize[i].max_widthdo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "max: " << pIconSize [i].max_width << ", " << pIconSize[i].max_height) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1037 | << ", "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "max: " << pIconSize [i].max_width << ", " << pIconSize[i].max_height) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1038 | << pIconSize[i].max_height)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "max: " << pIconSize [i].max_width << ", " << pIconSize[i].max_height) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "max: " << pIconSize[i].max_width << ", " << pIconSize[i].max_height; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1038" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1039 | SAL_INFO("vcl.window", "inc: "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "inc: " << pIconSize [i].width_inc << ", " << pIconSize[i].height_inc) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1040 | << pIconSize[i].width_incdo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "inc: " << pIconSize [i].width_inc << ", " << pIconSize[i].height_inc) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1041 | << ", "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "inc: " << pIconSize [i].width_inc << ", " << pIconSize[i].height_inc) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1042 | << pIconSize[i].height_inc)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "inc: " << pIconSize [i].width_inc << ", " << pIconSize[i].height_inc) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "inc: " << pIconSize[i].width_inc << ", " << pIconSize[i].height_inc; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "1042" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1043 | #endif | |||
1044 | } | |||
1045 | ||||
1046 | XFree( pIconSize ); | |||
1047 | } | |||
1048 | else | |||
1049 | { | |||
1050 | const OUString& rWM( pDisplay_->getWMAdaptor()->getWindowManagerName() ); | |||
1051 | if( rWM == "KWin" ) // assume KDE is running | |||
1052 | iconSize = 48; | |||
1053 | static bool bGnomeIconSize = false; | |||
1054 | static bool bGnomeChecked = false; | |||
1055 | if( ! bGnomeChecked ) | |||
1056 | { | |||
1057 | bGnomeChecked=true; | |||
1058 | int nCount = 0; | |||
1059 | Atom* pProps = XListProperties( GetXDisplay(), | |||
1060 | GetDisplay()->GetRootWindow( m_nXScreen ), | |||
1061 | &nCount ); | |||
1062 | for( int i = 0; i < nCount && !bGnomeIconSize; i++ ) | |||
1063 | { | |||
1064 | char* pName = XGetAtomName( GetXDisplay(), pProps[i] ); | |||
1065 | if( pName ) | |||
1066 | { | |||
1067 | if( !strcmp( pName, "GNOME_PANEL_DESKTOP_AREA" ) ) | |||
1068 | bGnomeIconSize = true; | |||
1069 | XFree( pName ); | |||
1070 | } | |||
1071 | } | |||
1072 | if( pProps ) | |||
1073 | XFree( pProps ); | |||
1074 | } | |||
1075 | if( bGnomeIconSize ) | |||
1076 | iconSize = 48; | |||
1077 | } | |||
1078 | ||||
1079 | XWMHints Hints; | |||
1080 | Hints.flags = 0; | |||
1081 | XWMHints *pHints = XGetWMHints( GetXDisplay(), GetShellWindow() ); | |||
1082 | if( pHints ) | |||
1083 | { | |||
1084 | memcpy(&Hints, pHints, sizeof( XWMHints )); | |||
1085 | XFree( pHints ); | |||
1086 | } | |||
1087 | pHints = &Hints; | |||
1088 | ||||
1089 | NetWmIconData netwm_icon; | |||
1090 | bool bOk = lcl_SelectAppIconPixmap( GetDisplay(), m_nXScreen, | |||
1091 | nIcon, iconSize, | |||
1092 | pHints->icon_pixmap, pHints->icon_mask, netwm_icon ); | |||
1093 | if ( !bOk ) | |||
1094 | { | |||
1095 | // load default icon (0) | |||
1096 | bOk = lcl_SelectAppIconPixmap( GetDisplay(), m_nXScreen, | |||
1097 | 0, iconSize, | |||
1098 | pHints->icon_pixmap, pHints->icon_mask, netwm_icon ); | |||
1099 | } | |||
1100 | if( bOk ) | |||
1101 | { | |||
1102 | pHints->flags |= IconPixmapHint(1L << 2); | |||
1103 | if( pHints->icon_mask ) | |||
1104 | pHints->flags |= IconMaskHint(1L << 5); | |||
1105 | ||||
1106 | XSetWMHints( GetXDisplay(), GetShellWindow(), pHints ); | |||
1107 | if( !netwm_icon.empty() && GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_ICON )) | |||
1108 | XChangeProperty( GetXDisplay(), mhWindow, | |||
1109 | GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_ICON ), | |||
1110 | XA_CARDINAL((Atom) 6), 32, PropModeReplace0, reinterpret_cast<unsigned char*>(netwm_icon.data()), netwm_icon.size()); | |||
1111 | } | |||
1112 | ||||
1113 | } | |||
1114 | ||||
1115 | void X11SalFrame::SetMaxClientSize( long nWidth, long nHeight ) | |||
1116 | { | |||
1117 | if( IsChildWindow() ) | |||
1118 | return; | |||
1119 | ||||
1120 | if( !GetShellWindow() || | |||
1121 | (nStyle_ & (SalFrameStyleFlags::FLOAT|SalFrameStyleFlags::OWNERDRAWDECORATION) ) == SalFrameStyleFlags::FLOAT ) | |||
1122 | return; | |||
1123 | ||||
1124 | XSizeHints* pHints = XAllocSizeHints(); | |||
1125 | long nSupplied = 0; | |||
1126 | XGetWMNormalHints( GetXDisplay(), | |||
1127 | GetShellWindow(), | |||
1128 | pHints, | |||
1129 | &nSupplied | |||
1130 | ); | |||
1131 | pHints->max_width = nWidth; | |||
1132 | pHints->max_height = nHeight; | |||
1133 | pHints->flags |= PMaxSize(1L << 5); | |||
1134 | XSetWMNormalHints( GetXDisplay(), | |||
1135 | GetShellWindow(), | |||
1136 | pHints ); | |||
1137 | XFree( pHints ); | |||
1138 | } | |||
1139 | ||||
1140 | void X11SalFrame::SetMinClientSize( long nWidth, long nHeight ) | |||
1141 | { | |||
1142 | if( IsChildWindow() ) | |||
1143 | return; | |||
1144 | ||||
1145 | if( !GetShellWindow() || | |||
1146 | (nStyle_ & (SalFrameStyleFlags::FLOAT|SalFrameStyleFlags::OWNERDRAWDECORATION) ) == SalFrameStyleFlags::FLOAT ) | |||
1147 | return; | |||
1148 | ||||
1149 | XSizeHints* pHints = XAllocSizeHints(); | |||
1150 | long nSupplied = 0; | |||
1151 | XGetWMNormalHints( GetXDisplay(), | |||
1152 | GetShellWindow(), | |||
1153 | pHints, | |||
1154 | &nSupplied | |||
1155 | ); | |||
1156 | pHints->min_width = nWidth; | |||
1157 | pHints->min_height = nHeight; | |||
1158 | pHints->flags |= PMinSize(1L << 4); | |||
1159 | XSetWMNormalHints( GetXDisplay(), | |||
1160 | GetShellWindow(), | |||
1161 | pHints ); | |||
1162 | XFree( pHints ); | |||
1163 | } | |||
1164 | ||||
1165 | // Show + Pos (x,y,z) + Size (width,height) | |||
1166 | ||||
1167 | void X11SalFrame::Show( bool bVisible, bool bNoActivate ) | |||
1168 | { | |||
1169 | if( ( bVisible && bMapped_ ) | |||
1170 | || ( !bVisible && !bMapped_ ) ) | |||
1171 | return; | |||
1172 | ||||
1173 | // HACK: this is a workaround for (at least) kwin | |||
1174 | // even though transient frames should be kept above their parent | |||
1175 | // this does not necessarily hold true for DOCK type windows | |||
1176 | // so artificially set ABOVE and remove it again on hide | |||
1177 | if( mpParent && (mpParent->nStyle_ & SalFrameStyleFlags::PARTIAL_FULLSCREEN ) && pDisplay_->getWMAdaptor()->isLegacyPartialFullscreen()) | |||
1178 | pDisplay_->getWMAdaptor()->enableAlwaysOnTop( this, bVisible ); | |||
1179 | ||||
1180 | bMapped_ = bVisible; | |||
1181 | bViewable_ = bVisible; | |||
1182 | setXEmbedInfo(); | |||
1183 | if( bVisible ) | |||
1184 | { | |||
1185 | if( ! (nStyle_ & SalFrameStyleFlags::INTRO) ) | |||
1186 | { | |||
1187 | // hide all INTRO frames | |||
1188 | for (auto pSalFrame : GetDisplay()->getFrames() ) | |||
1189 | { | |||
1190 | const X11SalFrame* pFrame = static_cast< const X11SalFrame* >( pSalFrame ); | |||
1191 | // look for intro bit map; if present, hide it | |||
1192 | if( pFrame->nStyle_ & SalFrameStyleFlags::INTRO ) | |||
1193 | { | |||
1194 | if( pFrame->bMapped_ ) | |||
1195 | const_cast<X11SalFrame*>(pFrame)->Show( false ); | |||
1196 | } | |||
1197 | } | |||
1198 | } | |||
1199 | ||||
1200 | // update NET_WM_STATE which may have been deleted due to earlier Show(false) | |||
1201 | if( nShowState_ == SHOWSTATE_HIDDEN2 ) | |||
1202 | GetDisplay()->getWMAdaptor()->frameIsMapping( this ); | |||
1203 | ||||
1204 | /* | |||
1205 | * Actually this is rather exotic and currently happens only in conjunction | |||
1206 | * with the basic dialogue editor, | |||
1207 | * which shows a frame and instantly hides it again. After that the | |||
1208 | * editor window is shown and the WM takes this as an opportunity | |||
1209 | * to show our hidden transient frame also. So Show( false ) must | |||
1210 | * withdraw the frame AND delete the WM_TRANSIENT_FOR property. | |||
1211 | * In case the frame is shown again, the transient hint must be restored here. | |||
1212 | */ | |||
1213 | if( ! IsChildWindow() | |||
1214 | && ! IsOverrideRedirect() | |||
1215 | && ! IsFloatGrabWindow() | |||
1216 | && mpParent | |||
1217 | ) | |||
1218 | { | |||
1219 | GetDisplay()->getWMAdaptor()->changeReferenceFrame( this, mpParent ); | |||
1220 | } | |||
1221 | ||||
1222 | // #i45160# switch to desktop where a dialog with parent will appear | |||
1223 | if( mpParent && mpParent->m_nWorkArea != m_nWorkArea ) | |||
1224 | GetDisplay()->getWMAdaptor()->switchToWorkArea( mpParent->m_nWorkArea ); | |||
1225 | ||||
1226 | if( IsFloatGrabWindow() && | |||
1227 | mpParent && | |||
1228 | nVisibleFloats == 0 && | |||
1229 | ! GetDisplay()->GetCaptureFrame() ) | |||
1230 | { | |||
1231 | /* #i39420# | |||
1232 | * outsmart KWin's "focus strictly under mouse" mode | |||
1233 | * which insists on taking the focus from the document | |||
1234 | * to the new float. Grab focus to parent frame BEFORE | |||
1235 | * showing the float (cannot grab it to the float | |||
1236 | * before show). | |||
1237 | */ | |||
1238 | XGrabPointer( GetXDisplay(), | |||
1239 | mpParent->GetWindow(), | |||
1240 | True1, | |||
1241 | PointerMotionMask(1L<<6) | ButtonPressMask(1L<<2) | ButtonReleaseMask(1L<<3), | |||
1242 | GrabModeAsync1, | |||
1243 | GrabModeAsync1, | |||
1244 | None0L, | |||
1245 | mpParent ? mpParent->GetCursor() : None0L, | |||
1246 | CurrentTime0L | |||
1247 | ); | |||
1248 | } | |||
1249 | ||||
1250 | Time nUserTime = 0; | |||
1251 | if( ! bNoActivate && !(nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ) | |||
1252 | nUserTime = pDisplay_->GetX11ServerTime(); | |||
1253 | GetDisplay()->getWMAdaptor()->setUserTime( this, nUserTime ); | |||
1254 | if( ! bNoActivate && (nStyle_ & SalFrameStyleFlags::TOOLWINDOW) ) | |||
1255 | m_bSetFocusOnMap = true; | |||
1256 | ||||
1257 | // actually map the window | |||
1258 | if( m_bXEmbed ) | |||
1259 | askForXEmbedFocus( 0 ); | |||
1260 | else | |||
1261 | { | |||
1262 | if( GetWindow() != GetShellWindow() && ! IsSysChildWindow() ) | |||
1263 | { | |||
1264 | if( IsChildWindow() ) | |||
1265 | XMapWindow( GetXDisplay(), GetShellWindow() ); | |||
1266 | XSelectInput( GetXDisplay(), GetShellWindow(), CLIENT_EVENTS ); | |||
1267 | } | |||
1268 | if( nStyle_ & SalFrameStyleFlags::FLOAT ) | |||
1269 | XMapRaised( GetXDisplay(), GetWindow() ); | |||
1270 | else | |||
1271 | XMapWindow( GetXDisplay(), GetWindow() ); | |||
1272 | } | |||
1273 | XSelectInput( GetXDisplay(), GetWindow(), CLIENT_EVENTS ); | |||
1274 | ||||
1275 | if( maGeometry.nWidth > 0 | |||
1276 | && maGeometry.nHeight > 0 | |||
1277 | && ( nWidth_ != static_cast<int>(maGeometry.nWidth) | |||
1278 | || nHeight_ != static_cast<int>(maGeometry.nHeight) ) ) | |||
1279 | { | |||
1280 | nWidth_ = maGeometry.nWidth; | |||
1281 | nHeight_ = maGeometry.nHeight; | |||
1282 | } | |||
1283 | ||||
1284 | XSync( GetXDisplay(), False0 ); | |||
1285 | ||||
1286 | if( IsFloatGrabWindow() ) | |||
1287 | { | |||
1288 | /* | |||
1289 | * Sawfish and twm can be switched to enter-exit focus behaviour. In this case | |||
1290 | * we must grab the pointer else the dumb WM will put the focus to the | |||
1291 | * override-redirect float window. The application window will be deactivated | |||
1292 | * which causes that the floats are destroyed, so the user can never click on | |||
1293 | * a menu because it vanishes as soon as he enters it. | |||
1294 | */ | |||
1295 | nVisibleFloats++; | |||
1296 | if( nVisibleFloats == 1 && ! GetDisplay()->GetCaptureFrame() ) | |||
1297 | { | |||
1298 | /* #i39420# now move grab to the new float window */ | |||
1299 | XGrabPointer( GetXDisplay(), | |||
1300 | GetWindow(), | |||
1301 | True1, | |||
1302 | PointerMotionMask(1L<<6) | ButtonPressMask(1L<<2) | ButtonReleaseMask(1L<<3), | |||
1303 | GrabModeAsync1, | |||
1304 | GrabModeAsync1, | |||
1305 | None0L, | |||
1306 | mpParent ? mpParent->GetCursor() : None0L, | |||
1307 | CurrentTime0L | |||
1308 | ); | |||
1309 | } | |||
1310 | } | |||
1311 | CallCallback( SalEvent::Resize, nullptr ); | |||
1312 | ||||
1313 | /* | |||
1314 | * sometimes a message box/dialogue is brought up when a frame is not mapped | |||
1315 | * the corresponding TRANSIENT_FOR hint is then set to the root window | |||
1316 | * so that the dialogue shows in all cases. Correct it here if the | |||
1317 | * frame is shown afterwards. | |||
1318 | */ | |||
1319 | if( ! IsChildWindow() | |||
1320 | && ! IsOverrideRedirect() | |||
1321 | && ! IsFloatGrabWindow() | |||
1322 | ) | |||
1323 | { | |||
1324 | for (auto const& child : maChildren) | |||
1325 | { | |||
1326 | if( child->mbTransientForRoot ) | |||
1327 | GetDisplay()->getWMAdaptor()->changeReferenceFrame( child, this ); | |||
1328 | } | |||
1329 | } | |||
1330 | /* | |||
1331 | * leave SHOWSTATE_UNKNOWN as this indicates first mapping | |||
1332 | * and is only reset int HandleSizeEvent | |||
1333 | */ | |||
1334 | if( nShowState_ != SHOWSTATE_UNKNOWN-1 ) | |||
1335 | nShowState_ = SHOWSTATE_NORMAL1; | |||
1336 | ||||
1337 | /* | |||
1338 | * plugged windows don't necessarily get the | |||
1339 | * focus on show because the parent may already be mapped | |||
1340 | * and have the focus. So try to set the focus | |||
1341 | * to the child on Show(true) | |||
1342 | */ | |||
1343 | if( (nStyle_ & SalFrameStyleFlags::PLUG) && ! m_bXEmbed ) | |||
1344 | XSetInputFocus( GetXDisplay(), | |||
1345 | GetWindow(), | |||
1346 | RevertToParent2, | |||
1347 | CurrentTime0L ); | |||
1348 | ||||
1349 | if( mpParent ) | |||
1350 | { | |||
1351 | // push this frame so it will be in front of its siblings | |||
1352 | // only necessary for insane transient behaviour of Dtwm/olwm | |||
1353 | mpParent->maChildren.remove( this ); | |||
1354 | mpParent->maChildren.push_front(this); | |||
1355 | } | |||
1356 | } | |||
1357 | else | |||
1358 | { | |||
1359 | if( getInputContext() ) | |||
1360 | getInputContext()->Unmap(); | |||
1361 | ||||
1362 | if( ! IsChildWindow() ) | |||
1363 | { | |||
1364 | /* FIXME: Is deleting the property really necessary ? It hurts | |||
1365 | * owner drawn windows at least. | |||
1366 | */ | |||
1367 | if( mpParent && ! (nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ) | |||
1368 | XDeleteProperty( GetXDisplay(), GetShellWindow(), GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::WM_TRANSIENT_FOR ) ); | |||
1369 | XWithdrawWindow( GetXDisplay(), GetShellWindow(), m_nXScreen.getXScreen() ); | |||
1370 | } | |||
1371 | else if( ! m_bXEmbed ) | |||
1372 | XUnmapWindow( GetXDisplay(), GetWindow() ); | |||
1373 | ||||
1374 | nShowState_ = SHOWSTATE_HIDDEN2; | |||
1375 | if( IsFloatGrabWindow() && nVisibleFloats ) | |||
1376 | { | |||
1377 | nVisibleFloats--; | |||
1378 | if( nVisibleFloats == 0 && ! GetDisplay()->GetCaptureFrame() ) | |||
1379 | XUngrabPointer( GetXDisplay(), | |||
1380 | CurrentTime0L ); | |||
1381 | } | |||
1382 | // flush here; there may be a very seldom race between | |||
1383 | // the display connection used for clipboard and our connection | |||
1384 | Flush(); | |||
1385 | } | |||
1386 | } | |||
1387 | ||||
1388 | void X11SalFrame::ToTop( SalFrameToTop nFlags ) | |||
1389 | { | |||
1390 | if( ( nFlags & SalFrameToTop::RestoreWhenMin ) | |||
1391 | && ! ( nStyle_ & SalFrameStyleFlags::FLOAT ) | |||
1392 | && nShowState_ != SHOWSTATE_HIDDEN2 | |||
1393 | && nShowState_ != SHOWSTATE_UNKNOWN-1 | |||
1394 | ) | |||
1395 | { | |||
1396 | GetDisplay()->getWMAdaptor()->frameIsMapping( this ); | |||
1397 | if( GetWindow() != GetShellWindow() && ! IsSysChildWindow() ) | |||
1398 | XMapWindow( GetXDisplay(), GetShellWindow() ); | |||
1399 | XMapWindow( GetXDisplay(), GetWindow() ); | |||
1400 | } | |||
1401 | ||||
1402 | ::Window aToTopWindow = IsSysChildWindow() ? GetWindow() : GetShellWindow(); | |||
1403 | if( ! (nFlags & SalFrameToTop::GrabFocusOnly) ) | |||
1404 | { | |||
1405 | XRaiseWindow( GetXDisplay(), aToTopWindow ); | |||
1406 | } | |||
1407 | ||||
1408 | if( ( ( nFlags & SalFrameToTop::GrabFocus ) || ( nFlags & SalFrameToTop::GrabFocusOnly ) ) | |||
1409 | && bMapped_ ) | |||
1410 | { | |||
1411 | if( m_bXEmbed ) | |||
1412 | askForXEmbedFocus( 0 ); | |||
1413 | else | |||
1414 | XSetInputFocus( GetXDisplay(), aToTopWindow, RevertToParent2, CurrentTime0L ); | |||
1415 | } | |||
1416 | else if( ( nFlags & SalFrameToTop::RestoreWhenMin ) || ( nFlags & SalFrameToTop::ForegroundTask ) ) | |||
1417 | { | |||
1418 | Time nTimestamp = pDisplay_->GetX11ServerTime(); | |||
1419 | GetDisplay()->getWMAdaptor()->activateWindow( this, nTimestamp ); | |||
1420 | } | |||
1421 | } | |||
1422 | ||||
1423 | void X11SalFrame::GetWorkArea( tools::Rectangle& rWorkArea ) | |||
1424 | { | |||
1425 | rWorkArea = pDisplay_->getWMAdaptor()->getWorkArea( 0 ); | |||
1426 | } | |||
1427 | ||||
1428 | void X11SalFrame::GetClientSize( long &rWidth, long &rHeight ) | |||
1429 | { | |||
1430 | if( ! bViewable_ ) | |||
1431 | { | |||
1432 | rWidth = rHeight = 0; | |||
1433 | return; | |||
1434 | } | |||
1435 | ||||
1436 | rWidth = maGeometry.nWidth; | |||
1437 | rHeight = maGeometry.nHeight; | |||
1438 | ||||
1439 | if( !rWidth || !rHeight ) | |||
1440 | { | |||
1441 | XWindowAttributes aAttrib; | |||
1442 | ||||
1443 | XGetWindowAttributes( GetXDisplay(), GetWindow(), &aAttrib ); | |||
1444 | ||||
1445 | maGeometry.nWidth = rWidth = aAttrib.width; | |||
1446 | maGeometry.nHeight = rHeight = aAttrib.height; | |||
1447 | } | |||
1448 | } | |||
1449 | ||||
1450 | void X11SalFrame::Center( ) | |||
1451 | { | |||
1452 | int nX, nY, nScreenWidth, nScreenHeight; | |||
1453 | int nRealScreenWidth, nRealScreenHeight; | |||
1454 | int nScreenX = 0, nScreenY = 0; | |||
1455 | ||||
1456 | const Size& aScreenSize = GetDisplay()->getDataForScreen( m_nXScreen ).m_aSize; | |||
1457 | nScreenWidth = aScreenSize.Width(); | |||
1458 | nScreenHeight = aScreenSize.Height(); | |||
1459 | nRealScreenWidth = nScreenWidth; | |||
1460 | nRealScreenHeight = nScreenHeight; | |||
1461 | ||||
1462 | if( GetDisplay()->IsXinerama() ) | |||
1463 | { | |||
1464 | // get xinerama screen we are on | |||
1465 | // if there is a parent, use its center for screen determination | |||
1466 | // else use the pointer | |||
1467 | ::Window aRoot, aChild; | |||
1468 | int root_x, root_y, x, y; | |||
1469 | unsigned int mask; | |||
1470 | if( mpParent ) | |||
1471 | { | |||
1472 | root_x = mpParent->maGeometry.nX + mpParent->maGeometry.nWidth/2; | |||
1473 | root_y = mpParent->maGeometry.nY + mpParent->maGeometry.nHeight/2; | |||
1474 | } | |||
1475 | else | |||
1476 | XQueryPointer( GetXDisplay(), | |||
1477 | GetShellWindow(), | |||
1478 | &aRoot, &aChild, | |||
1479 | &root_x, &root_y, | |||
1480 | &x, &y, | |||
1481 | &mask ); | |||
1482 | const std::vector< tools::Rectangle >& rScreens = GetDisplay()->GetXineramaScreens(); | |||
1483 | for(const auto & rScreen : rScreens) | |||
1484 | if( rScreen.IsInside( Point( root_x, root_y ) ) ) | |||
1485 | { | |||
1486 | nScreenX = rScreen.Left(); | |||
1487 | nScreenY = rScreen.Top(); | |||
1488 | nRealScreenWidth = rScreen.GetWidth(); | |||
1489 | nRealScreenHeight = rScreen.GetHeight(); | |||
1490 | break; | |||
1491 | } | |||
1492 | } | |||
1493 | ||||
1494 | if( mpParent ) | |||
1495 | { | |||
1496 | X11SalFrame* pFrame = mpParent; | |||
1497 | while( pFrame->mpParent ) | |||
1498 | pFrame = pFrame->mpParent; | |||
1499 | if( pFrame->maGeometry.nWidth < 1 || pFrame->maGeometry.nHeight < 1 ) | |||
1500 | { | |||
1501 | tools::Rectangle aRect; | |||
1502 | pFrame->GetPosSize( aRect ); | |||
1503 | pFrame->maGeometry.nX = aRect.Left(); | |||
1504 | pFrame->maGeometry.nY = aRect.Top(); | |||
1505 | pFrame->maGeometry.nWidth = aRect.GetWidth(); | |||
1506 | pFrame->maGeometry.nHeight = aRect.GetHeight(); | |||
1507 | } | |||
1508 | ||||
1509 | if( pFrame->nStyle_ & SalFrameStyleFlags::PLUG ) | |||
1510 | { | |||
1511 | ::Window aRoot; | |||
1512 | unsigned int bw, depth; | |||
1513 | XGetGeometry( GetXDisplay(), | |||
1514 | pFrame->GetShellWindow(), | |||
1515 | &aRoot, | |||
1516 | &nScreenX, &nScreenY, | |||
1517 | reinterpret_cast<unsigned int*>(&nScreenWidth), | |||
1518 | reinterpret_cast<unsigned int*>(&nScreenHeight), | |||
1519 | &bw, &depth ); | |||
1520 | } | |||
1521 | else | |||
1522 | { | |||
1523 | nScreenX = pFrame->maGeometry.nX; | |||
1524 | nScreenY = pFrame->maGeometry.nY; | |||
1525 | nScreenWidth = pFrame->maGeometry.nWidth; | |||
1526 | nScreenHeight = pFrame->maGeometry.nHeight; | |||
1527 | } | |||
1528 | } | |||
1529 | ||||
1530 | if( mpParent && mpParent->nShowState_ == SHOWSTATE_NORMAL1 ) | |||
1531 | { | |||
1532 | if( maGeometry.nWidth >= mpParent->maGeometry.nWidth && | |||
1533 | maGeometry.nHeight >= mpParent->maGeometry.nHeight ) | |||
1534 | { | |||
1535 | nX = nScreenX + 40; | |||
1536 | nY = nScreenY + 40; | |||
1537 | } | |||
1538 | else | |||
1539 | { | |||
1540 | // center the window relative to the top level frame | |||
1541 | nX = (nScreenWidth - static_cast<int>(maGeometry.nWidth) ) / 2 + nScreenX; | |||
1542 | nY = (nScreenHeight - static_cast<int>(maGeometry.nHeight)) / 2 + nScreenY; | |||
1543 | } | |||
1544 | } | |||
1545 | else | |||
1546 | { | |||
1547 | // center the window relative to screen | |||
1548 | nX = (nRealScreenWidth - static_cast<int>(maGeometry.nWidth) ) / 2 + nScreenX; | |||
1549 | nY = (nRealScreenHeight - static_cast<int>(maGeometry.nHeight)) / 2 + nScreenY; | |||
1550 | } | |||
1551 | nX = nX < 0 ? 0 : nX; | |||
1552 | nY = nY < 0 ? 0 : nY; | |||
1553 | ||||
1554 | bDefaultPosition_ = False0; | |||
1555 | if( mpParent ) | |||
1556 | { | |||
1557 | nX -= mpParent->maGeometry.nX; | |||
1558 | nY -= mpParent->maGeometry.nY; | |||
1559 | } | |||
1560 | ||||
1561 | Point aPoint(nX, nY); | |||
1562 | SetPosSize( tools::Rectangle( aPoint, Size( maGeometry.nWidth, maGeometry.nHeight ) ) ); | |||
1563 | } | |||
1564 | ||||
1565 | void X11SalFrame::updateScreenNumber() | |||
1566 | { | |||
1567 | if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 ) | |||
1568 | { | |||
1569 | Point aPoint( maGeometry.nX, maGeometry.nY ); | |||
1570 | const std::vector<tools::Rectangle>& rScreenRects( GetDisplay()->GetXineramaScreens() ); | |||
1571 | size_t nScreens = rScreenRects.size(); | |||
1572 | for( size_t i = 0; i < nScreens; i++ ) | |||
1573 | { | |||
1574 | if( rScreenRects[i].IsInside( aPoint ) ) | |||
1575 | { | |||
1576 | maGeometry.nDisplayScreenNumber = static_cast<unsigned int>(i); | |||
1577 | break; | |||
1578 | } | |||
1579 | } | |||
1580 | } | |||
1581 | else | |||
1582 | maGeometry.nDisplayScreenNumber = m_nXScreen.getXScreen(); | |||
1583 | } | |||
1584 | ||||
1585 | void X11SalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ) | |||
1586 | { | |||
1587 | if( nStyle_ & SalFrameStyleFlags::PLUG ) | |||
1588 | return; | |||
1589 | ||||
1590 | // relative positioning in X11SalFrame::SetPosSize | |||
1591 | tools::Rectangle aPosSize( Point( maGeometry.nX, maGeometry.nY ), Size( maGeometry.nWidth, maGeometry.nHeight ) ); | |||
1592 | aPosSize.Justify(); | |||
1593 | ||||
1594 | if( ! ( nFlags & SAL_FRAME_POSSIZE_X(sal_uInt16(0x0001)) ) ) | |||
1595 | { | |||
1596 | nX = aPosSize.Left(); | |||
1597 | if( mpParent ) | |||
1598 | nX -= mpParent->maGeometry.nX; | |||
1599 | } | |||
1600 | if( ! ( nFlags & SAL_FRAME_POSSIZE_Y(sal_uInt16(0x0002)) ) ) | |||
1601 | { | |||
1602 | nY = aPosSize.Top(); | |||
1603 | if( mpParent ) | |||
1604 | nY -= mpParent->maGeometry.nY; | |||
1605 | } | |||
1606 | if( ! ( nFlags & SAL_FRAME_POSSIZE_WIDTH(sal_uInt16(0x0004)) ) ) | |||
1607 | nWidth = aPosSize.GetWidth(); | |||
1608 | if( ! ( nFlags & SAL_FRAME_POSSIZE_HEIGHT(sal_uInt16(0x0008)) ) ) | |||
1609 | nHeight = aPosSize.GetHeight(); | |||
1610 | ||||
1611 | aPosSize = tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ); | |||
1612 | ||||
1613 | if( ! ( nFlags & ( SAL_FRAME_POSSIZE_X(sal_uInt16(0x0001)) | SAL_FRAME_POSSIZE_Y(sal_uInt16(0x0002)) ) ) ) | |||
1614 | { | |||
1615 | if( bDefaultPosition_ ) | |||
1616 | { | |||
1617 | maGeometry.nWidth = aPosSize.GetWidth(); | |||
1618 | maGeometry.nHeight = aPosSize.GetHeight(); | |||
1619 | Center(); | |||
1620 | } | |||
1621 | else | |||
1622 | SetSize( Size( nWidth, nHeight ) ); | |||
1623 | } | |||
1624 | else | |||
1625 | SetPosSize( aPosSize ); | |||
1626 | ||||
1627 | bDefaultPosition_ = False0; | |||
1628 | } | |||
1629 | ||||
1630 | void X11SalFrame::SetAlwaysOnTop( bool bOnTop ) | |||
1631 | { | |||
1632 | if( ! IsOverrideRedirect() ) | |||
1633 | { | |||
1634 | bAlwaysOnTop_ = bOnTop; | |||
1635 | pDisplay_->getWMAdaptor()->enableAlwaysOnTop( this, bOnTop ); | |||
1636 | } | |||
1637 | } | |||
1638 | ||||
1639 | constexpr auto FRAMESTATE_MASK_GEOMETRY = | |||
1640 | WindowStateMask::X | WindowStateMask::Y | | |||
1641 | WindowStateMask::Width | WindowStateMask::Height; | |||
1642 | constexpr auto FRAMESTATE_MASK_MAXIMIZED_GEOMETRY = | |||
1643 | WindowStateMask::MaximizedX | WindowStateMask::MaximizedY | | |||
1644 | WindowStateMask::MaximizedWidth | WindowStateMask::MaximizedHeight; | |||
1645 | ||||
1646 | void X11SalFrame::SetWindowState( const SalFrameState *pState ) | |||
1647 | { | |||
1648 | if (pState == nullptr) | |||
1649 | return; | |||
1650 | ||||
1651 | // Request for position or size change | |||
1652 | if (pState->mnMask & FRAMESTATE_MASK_GEOMETRY) | |||
1653 | { | |||
1654 | /* #i44325# | |||
1655 | * if maximized, set restore size and guess maximized size from last time | |||
1656 | * in state change below maximize window | |||
1657 | */ | |||
1658 | if( ! IsChildWindow() && | |||
1659 | (pState->mnMask & WindowStateMask::State) && | |||
1660 | (pState->mnState & WindowStateState::Maximized) && | |||
1661 | (pState->mnMask & FRAMESTATE_MASK_GEOMETRY) == FRAMESTATE_MASK_GEOMETRY && | |||
1662 | (pState->mnMask & FRAMESTATE_MASK_MAXIMIZED_GEOMETRY) == FRAMESTATE_MASK_MAXIMIZED_GEOMETRY | |||
1663 | ) | |||
1664 | { | |||
1665 | XSizeHints* pHints = XAllocSizeHints(); | |||
1666 | long nSupplied = 0; | |||
1667 | XGetWMNormalHints( GetXDisplay(), | |||
1668 | GetShellWindow(), | |||
1669 | pHints, | |||
1670 | &nSupplied ); | |||
1671 | pHints->flags |= PPosition(1L << 2) | PWinGravity(1L << 9); | |||
1672 | pHints->x = pState->mnX; | |||
1673 | pHints->y = pState->mnY; | |||
1674 | pHints->win_gravity = pDisplay_->getWMAdaptor()->getPositionWinGravity(); | |||
1675 | XSetWMNormalHints( GetXDisplay(), | |||
1676 | GetShellWindow(), | |||
1677 | pHints ); | |||
1678 | XFree( pHints ); | |||
1679 | ||||
1680 | XMoveResizeWindow( GetXDisplay(), GetShellWindow(), | |||
1681 | pState->mnX, pState->mnY, | |||
1682 | pState->mnWidth, pState->mnHeight ); | |||
1683 | // guess maximized geometry from last time | |||
1684 | maGeometry.nX = pState->mnMaximizedX; | |||
1685 | maGeometry.nY = pState->mnMaximizedY; | |||
1686 | maGeometry.nWidth = pState->mnMaximizedWidth; | |||
1687 | maGeometry.nHeight = pState->mnMaximizedHeight; | |||
1688 | updateScreenNumber(); | |||
1689 | } | |||
1690 | else | |||
1691 | { | |||
1692 | bool bDoAdjust = false; | |||
1693 | tools::Rectangle aPosSize; | |||
1694 | // initialize with current geometry | |||
1695 | if ((pState->mnMask & FRAMESTATE_MASK_GEOMETRY) != FRAMESTATE_MASK_GEOMETRY) | |||
1696 | GetPosSize (aPosSize); | |||
1697 | ||||
1698 | // change requested properties | |||
1699 | if (pState->mnMask & WindowStateMask::X) | |||
1700 | { | |||
1701 | aPosSize.setX (pState->mnX); | |||
1702 | } | |||
1703 | if (pState->mnMask & WindowStateMask::Y) | |||
1704 | { | |||
1705 | aPosSize.setY (pState->mnY); | |||
1706 | } | |||
1707 | if (pState->mnMask & WindowStateMask::Width) | |||
1708 | { | |||
1709 | long nWidth = pState->mnWidth > 0 ? pState->mnWidth - 1 : 0; | |||
1710 | aPosSize.setWidth (nWidth); | |||
1711 | bDoAdjust = true; | |||
1712 | } | |||
1713 | if (pState->mnMask & WindowStateMask::Height) | |||
1714 | { | |||
1715 | int nHeight = pState->mnHeight > 0 ? pState->mnHeight - 1 : 0; | |||
1716 | aPosSize.setHeight (nHeight); | |||
1717 | bDoAdjust = true; | |||
1718 | } | |||
1719 | ||||
1720 | const Size& aScreenSize = pDisplay_->getDataForScreen( m_nXScreen ).m_aSize; | |||
1721 | ||||
1722 | if( bDoAdjust && aPosSize.GetWidth() <= aScreenSize.Width() | |||
1723 | && aPosSize.GetHeight() <= aScreenSize.Height() ) | |||
1724 | { | |||
1725 | SalFrameGeometry aGeom = maGeometry; | |||
1726 | ||||
1727 | if( ! (nStyle_ & ( SalFrameStyleFlags::FLOAT | SalFrameStyleFlags::PLUG ) ) && | |||
1728 | mpParent && | |||
1729 | aGeom.nLeftDecoration == 0 && | |||
1730 | aGeom.nTopDecoration == 0 ) | |||
1731 | { | |||
1732 | aGeom = mpParent->maGeometry; | |||
1733 | if( aGeom.nLeftDecoration == 0 && | |||
1734 | aGeom.nTopDecoration == 0 ) | |||
1735 | { | |||
1736 | aGeom.nLeftDecoration = 5; | |||
1737 | aGeom.nTopDecoration = 20; | |||
1738 | aGeom.nRightDecoration = 5; | |||
1739 | aGeom.nBottomDecoration = 5; | |||
1740 | } | |||
1741 | } | |||
1742 | ||||
1743 | // adjust position so that frame fits onto screen | |||
1744 | if( aPosSize.Right()+static_cast<long>(aGeom.nRightDecoration) > aScreenSize.Width()-1 ) | |||
1745 | aPosSize.Move( aScreenSize.Width() - aPosSize.Right() - static_cast<long>(aGeom.nRightDecoration), 0 ); | |||
1746 | if( aPosSize.Bottom()+static_cast<long>(aGeom.nBottomDecoration) > aScreenSize.Height()-1 ) | |||
1747 | aPosSize.Move( 0, aScreenSize.Height() - aPosSize.Bottom() - static_cast<long>(aGeom.nBottomDecoration) ); | |||
1748 | if( aPosSize.Left() < static_cast<long>(aGeom.nLeftDecoration) ) | |||
1749 | aPosSize.Move( static_cast<long>(aGeom.nLeftDecoration) - aPosSize.Left(), 0 ); | |||
1750 | if( aPosSize.Top() < static_cast<long>(aGeom.nTopDecoration) ) | |||
1751 | aPosSize.Move( 0, static_cast<long>(aGeom.nTopDecoration) - aPosSize.Top() ); | |||
1752 | } | |||
1753 | ||||
1754 | SetPosSize( 0, 0, aPosSize.GetWidth(), aPosSize.GetHeight(), SAL_FRAME_POSSIZE_WIDTH(sal_uInt16(0x0004)) | SAL_FRAME_POSSIZE_HEIGHT(sal_uInt16(0x0008)) ); | |||
1755 | } | |||
1756 | } | |||
1757 | ||||
1758 | // request for status change | |||
1759 | if (!(pState->mnMask & WindowStateMask::State)) | |||
1760 | return; | |||
1761 | ||||
1762 | if (pState->mnState & WindowStateState::Maximized) | |||
1763 | { | |||
1764 | nShowState_ = SHOWSTATE_NORMAL1; | |||
1765 | if( ! (pState->mnState & (WindowStateState::MaximizedHorz|WindowStateState::MaximizedVert) ) ) | |||
1766 | Maximize(); | |||
1767 | else | |||
1768 | { | |||
1769 | bool bHorz(pState->mnState & WindowStateState::MaximizedHorz); | |||
1770 | bool bVert(pState->mnState & WindowStateState::MaximizedVert); | |||
1771 | GetDisplay()->getWMAdaptor()->maximizeFrame( this, bHorz, bVert ); | |||
1772 | } | |||
1773 | maRestorePosSize.SetLeft( pState->mnX ); | |||
1774 | maRestorePosSize.SetTop( pState->mnY ); | |||
1775 | maRestorePosSize.SetRight( maRestorePosSize.Left() + pState->mnWidth ); | |||
1776 | maRestorePosSize.SetRight( maRestorePosSize.Left() + pState->mnHeight ); | |||
1777 | } | |||
1778 | else if( mbMaximizedHorz || mbMaximizedVert ) | |||
1779 | GetDisplay()->getWMAdaptor()->maximizeFrame( this, false, false ); | |||
1780 | ||||
1781 | if (pState->mnState & WindowStateState::Minimized) | |||
1782 | { | |||
1783 | if (nShowState_ == SHOWSTATE_UNKNOWN-1) | |||
1784 | nShowState_ = SHOWSTATE_NORMAL1; | |||
1785 | Minimize(); | |||
1786 | } | |||
1787 | if (pState->mnState & WindowStateState::Normal) | |||
1788 | { | |||
1789 | if (nShowState_ != SHOWSTATE_NORMAL1) | |||
1790 | Restore(); | |||
1791 | } | |||
1792 | if (pState->mnState & WindowStateState::Rollup) | |||
1793 | GetDisplay()->getWMAdaptor()->shade( this, true ); | |||
1794 | } | |||
1795 | ||||
1796 | bool X11SalFrame::GetWindowState( SalFrameState* pState ) | |||
1797 | { | |||
1798 | if( SHOWSTATE_MINIMIZED0 == nShowState_ ) | |||
1799 | pState->mnState = WindowStateState::Minimized; | |||
1800 | else | |||
1801 | pState->mnState = WindowStateState::Normal; | |||
1802 | ||||
1803 | tools::Rectangle aPosSize; | |||
1804 | if( maRestorePosSize.IsEmpty() ) | |||
1805 | GetPosSize( aPosSize ); | |||
1806 | else | |||
1807 | aPosSize = maRestorePosSize; | |||
1808 | ||||
1809 | if( mbMaximizedHorz ) | |||
1810 | pState->mnState |= WindowStateState::MaximizedHorz; | |||
1811 | if( mbMaximizedVert ) | |||
1812 | pState->mnState |= WindowStateState::MaximizedVert; | |||
1813 | if( mbShaded ) | |||
1814 | pState->mnState |= WindowStateState::Rollup; | |||
1815 | ||||
1816 | pState->mnX = aPosSize.Left(); | |||
1817 | pState->mnY = aPosSize.Top(); | |||
1818 | pState->mnWidth = aPosSize.GetWidth(); | |||
1819 | pState->mnHeight = aPosSize.GetHeight(); | |||
1820 | ||||
1821 | pState->mnMask = FRAMESTATE_MASK_GEOMETRY | WindowStateMask::State; | |||
1822 | ||||
1823 | if (! maRestorePosSize.IsEmpty() ) | |||
1824 | { | |||
1825 | GetPosSize( aPosSize ); | |||
1826 | pState->mnState |= WindowStateState::Maximized; | |||
1827 | pState->mnMaximizedX = aPosSize.Left(); | |||
1828 | pState->mnMaximizedY = aPosSize.Top(); | |||
1829 | pState->mnMaximizedWidth = aPosSize.GetWidth(); | |||
1830 | pState->mnMaximizedHeight = aPosSize.GetHeight(); | |||
1831 | pState->mnMask |= FRAMESTATE_MASK_MAXIMIZED_GEOMETRY; | |||
1832 | } | |||
1833 | ||||
1834 | return true; | |||
1835 | } | |||
1836 | ||||
1837 | // native menu implementation - currently empty | |||
1838 | void X11SalFrame::DrawMenuBar() | |||
1839 | { | |||
1840 | } | |||
1841 | ||||
1842 | void X11SalFrame::SetMenu( SalMenu* ) | |||
1843 | { | |||
1844 | } | |||
1845 | ||||
1846 | void X11SalFrame::GetPosSize( tools::Rectangle &rPosSize ) | |||
1847 | { | |||
1848 | if( maGeometry.nWidth < 1 || maGeometry.nHeight < 1 ) | |||
1849 | { | |||
1850 | const Size& aScreenSize = pDisplay_->getDataForScreen( m_nXScreen ).m_aSize; | |||
1851 | long w = aScreenSize.Width() - maGeometry.nLeftDecoration - maGeometry.nRightDecoration; | |||
1852 | long h = aScreenSize.Height() - maGeometry.nTopDecoration - maGeometry.nBottomDecoration; | |||
1853 | ||||
1854 | rPosSize = tools::Rectangle( Point( maGeometry.nX, maGeometry.nY ), Size( w, h ) ); | |||
1855 | } | |||
1856 | else | |||
1857 | rPosSize = tools::Rectangle( Point( maGeometry.nX, maGeometry.nY ), | |||
1858 | Size( maGeometry.nWidth, maGeometry.nHeight ) ); | |||
1859 | } | |||
1860 | ||||
1861 | void X11SalFrame::SetSize( const Size &rSize ) | |||
1862 | { | |||
1863 | if( rSize.IsEmpty() ) | |||
1864 | return; | |||
1865 | ||||
1866 | if( ! ( nStyle_ & SalFrameStyleFlags::SIZEABLE ) | |||
1867 | && ! IsChildWindow() | |||
1868 | && ( nStyle_ & (SalFrameStyleFlags::FLOAT|SalFrameStyleFlags::OWNERDRAWDECORATION) ) != SalFrameStyleFlags::FLOAT ) | |||
1869 | { | |||
1870 | XSizeHints* pHints = XAllocSizeHints(); | |||
1871 | long nSupplied = 0; | |||
1872 | XGetWMNormalHints( GetXDisplay(), | |||
1873 | GetShellWindow(), | |||
1874 | pHints, | |||
1875 | &nSupplied | |||
1876 | ); | |||
1877 | pHints->min_width = rSize.Width(); | |||
1878 | pHints->min_height = rSize.Height(); | |||
1879 | pHints->max_width = rSize.Width(); | |||
1880 | pHints->max_height = rSize.Height(); | |||
1881 | pHints->flags |= PMinSize(1L << 4) | PMaxSize(1L << 5); | |||
1882 | XSetWMNormalHints( GetXDisplay(), | |||
1883 | GetShellWindow(), | |||
1884 | pHints ); | |||
1885 | XFree( pHints ); | |||
1886 | } | |||
1887 | XResizeWindow( GetXDisplay(), IsSysChildWindow() ? GetWindow() : GetShellWindow(), rSize.Width(), rSize.Height() ); | |||
1888 | if( GetWindow() != GetShellWindow() ) | |||
1889 | { | |||
1890 | if( nStyle_ & SalFrameStyleFlags::PLUG ) | |||
1891 | XMoveResizeWindow( GetXDisplay(), GetWindow(), 0, 0, rSize.Width(), rSize.Height() ); | |||
1892 | else | |||
1893 | XResizeWindow( GetXDisplay(), GetWindow(), rSize.Width(), rSize.Height() ); | |||
1894 | } | |||
1895 | ||||
1896 | maGeometry.nWidth = rSize.Width(); | |||
1897 | maGeometry.nHeight = rSize.Height(); | |||
1898 | ||||
1899 | // allow the external status window to reposition | |||
1900 | if (mbInputFocus && mpInputContext != nullptr) | |||
1901 | mpInputContext->SetICFocus ( this ); | |||
1902 | } | |||
1903 | ||||
1904 | void X11SalFrame::SetPosSize( const tools::Rectangle &rPosSize ) | |||
1905 | { | |||
1906 | XWindowChanges values; | |||
1907 | values.x = rPosSize.Left(); | |||
1908 | values.y = rPosSize.Top(); | |||
1909 | values.width = rPosSize.GetWidth(); | |||
1910 | values.height = rPosSize.GetHeight(); | |||
1911 | ||||
1912 | if( !values.width || !values.height ) | |||
1913 | return; | |||
1914 | ||||
1915 | if( mpParent && ! IsSysChildWindow() ) | |||
1916 | { | |||
1917 | if( AllSettings::GetLayoutRTL() ) | |||
1918 | values.x = mpParent->maGeometry.nWidth-values.width-1-values.x; | |||
1919 | ||||
1920 | ::Window aChild; | |||
1921 | // coordinates are relative to parent, so translate to root coordinates | |||
1922 | XTranslateCoordinates( GetDisplay()->GetDisplay(), | |||
1923 | mpParent->GetWindow(), | |||
1924 | GetDisplay()->GetRootWindow( m_nXScreen ), | |||
1925 | values.x, values.y, | |||
1926 | &values.x, &values.y, | |||
1927 | & aChild ); | |||
1928 | } | |||
1929 | ||||
1930 | bool bMoved = false; | |||
1931 | bool bSized = false; | |||
1932 | if( values.x != maGeometry.nX || values.y != maGeometry.nY ) | |||
1933 | bMoved = true; | |||
1934 | if( values.width != static_cast<int>(maGeometry.nWidth) || values.height != static_cast<int>(maGeometry.nHeight) ) | |||
1935 | bSized = true; | |||
1936 | ||||
1937 | // do not set WMNormalHints for... | |||
1938 | if( | |||
1939 | // child windows | |||
1940 | ! IsChildWindow() | |||
1941 | // popups (menu, help window, etc.) | |||
1942 | && (nStyle_ & (SalFrameStyleFlags::FLOAT|SalFrameStyleFlags::OWNERDRAWDECORATION) ) != SalFrameStyleFlags::FLOAT | |||
1943 | // shown, sizeable windows | |||
1944 | && ( nShowState_ == SHOWSTATE_UNKNOWN-1 || | |||
1945 | nShowState_ == SHOWSTATE_HIDDEN2 || | |||
1946 | ! ( nStyle_ & SalFrameStyleFlags::SIZEABLE ) | |||
1947 | ) | |||
1948 | ) | |||
1949 | { | |||
1950 | XSizeHints* pHints = XAllocSizeHints(); | |||
1951 | long nSupplied = 0; | |||
1952 | XGetWMNormalHints( GetXDisplay(), | |||
1953 | GetShellWindow(), | |||
1954 | pHints, | |||
1955 | &nSupplied | |||
1956 | ); | |||
1957 | if( ! ( nStyle_ & SalFrameStyleFlags::SIZEABLE ) ) | |||
1958 | { | |||
1959 | pHints->min_width = rPosSize.GetWidth(); | |||
1960 | pHints->min_height = rPosSize.GetHeight(); | |||
1961 | pHints->max_width = rPosSize.GetWidth(); | |||
1962 | pHints->max_height = rPosSize.GetHeight(); | |||
1963 | pHints->flags |= PMinSize(1L << 4) | PMaxSize(1L << 5); | |||
1964 | } | |||
1965 | if( nShowState_ == SHOWSTATE_UNKNOWN-1 || nShowState_ == SHOWSTATE_HIDDEN2 ) | |||
1966 | { | |||
1967 | pHints->flags |= PPosition(1L << 2) | PWinGravity(1L << 9); | |||
1968 | pHints->x = values.x; | |||
1969 | pHints->y = values.y; | |||
1970 | pHints->win_gravity = pDisplay_->getWMAdaptor()->getPositionWinGravity(); | |||
1971 | } | |||
1972 | if( mbFullScreen ) | |||
1973 | { | |||
1974 | pHints->max_width = 10000; | |||
1975 | pHints->max_height = 10000; | |||
1976 | pHints->flags |= PMaxSize(1L << 5); | |||
1977 | } | |||
1978 | XSetWMNormalHints( GetXDisplay(), | |||
1979 | GetShellWindow(), | |||
1980 | pHints ); | |||
1981 | XFree( pHints ); | |||
1982 | } | |||
1983 | ||||
1984 | XMoveResizeWindow( GetXDisplay(), IsSysChildWindow() ? GetWindow() : GetShellWindow(), values.x, values.y, values.width, values.height ); | |||
1985 | if( GetShellWindow() != GetWindow() ) | |||
1986 | { | |||
1987 | if( nStyle_ & SalFrameStyleFlags::PLUG ) | |||
1988 | XMoveResizeWindow( GetXDisplay(), GetWindow(), 0, 0, values.width, values.height ); | |||
1989 | else | |||
1990 | XMoveResizeWindow( GetXDisplay(), GetWindow(), values.x, values.y, values.width, values.height ); | |||
1991 | } | |||
1992 | ||||
1993 | maGeometry.nX = values.x; | |||
1994 | maGeometry.nY = values.y; | |||
1995 | maGeometry.nWidth = values.width; | |||
1996 | maGeometry.nHeight = values.height; | |||
1997 | if( IsSysChildWindow() && mpParent ) | |||
1998 | { | |||
1999 | // translate back to root coordinates | |||
2000 | maGeometry.nX += mpParent->maGeometry.nX; | |||
2001 | maGeometry.nY += mpParent->maGeometry.nY; | |||
2002 | } | |||
2003 | ||||
2004 | updateScreenNumber(); | |||
2005 | if( bSized && ! bMoved ) | |||
2006 | CallCallback( SalEvent::Resize, nullptr ); | |||
2007 | else if( bMoved && ! bSized ) | |||
2008 | CallCallback( SalEvent::Move, nullptr ); | |||
2009 | else | |||
2010 | CallCallback( SalEvent::MoveResize, nullptr ); | |||
2011 | ||||
2012 | // allow the external status window to reposition | |||
2013 | if (mbInputFocus && mpInputContext != nullptr) | |||
2014 | mpInputContext->SetICFocus ( this ); | |||
2015 | } | |||
2016 | ||||
2017 | void X11SalFrame::Minimize() | |||
2018 | { | |||
2019 | if( IsSysChildWindow() ) | |||
2020 | return; | |||
2021 | ||||
2022 | if( SHOWSTATE_UNKNOWN-1 == nShowState_ || SHOWSTATE_HIDDEN2 == nShowState_ ) | |||
2023 | { | |||
2024 | SAL_WARN( "vcl", "X11SalFrame::Minimize on withdrawn window" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::Minimize on withdrawn window") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2024" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::Minimize on withdrawn window" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::Minimize on withdrawn window"; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2024" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::Minimize on withdrawn window") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2024" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::Minimize on withdrawn window" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::Minimize on withdrawn window"; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2024" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
2025 | return; | |||
2026 | } | |||
2027 | ||||
2028 | if( XIconifyWindow( GetXDisplay(), | |||
2029 | GetShellWindow(), | |||
2030 | pDisplay_->GetDefaultXScreen().getXScreen() ) ) | |||
2031 | nShowState_ = SHOWSTATE_MINIMIZED0; | |||
2032 | } | |||
2033 | ||||
2034 | void X11SalFrame::Maximize() | |||
2035 | { | |||
2036 | if( IsSysChildWindow() ) | |||
2037 | return; | |||
2038 | ||||
2039 | if( SHOWSTATE_MINIMIZED0 == nShowState_ ) | |||
2040 | { | |||
2041 | GetDisplay()->getWMAdaptor()->frameIsMapping( this ); | |||
2042 | XMapWindow( GetXDisplay(), GetShellWindow() ); | |||
2043 | nShowState_ = SHOWSTATE_NORMAL1; | |||
2044 | } | |||
2045 | ||||
2046 | pDisplay_->getWMAdaptor()->maximizeFrame( this ); | |||
2047 | } | |||
2048 | ||||
2049 | void X11SalFrame::Restore() | |||
2050 | { | |||
2051 | if( IsSysChildWindow() ) | |||
2052 | return; | |||
2053 | ||||
2054 | if( SHOWSTATE_UNKNOWN-1 == nShowState_ || SHOWSTATE_HIDDEN2 == nShowState_ ) | |||
2055 | { | |||
2056 | SAL_WARN( "vcl", "X11SalFrame::Restore on withdrawn window" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::Restore on withdrawn window") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ( "/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2056" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::Restore on withdrawn window" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::Restore on withdrawn window"; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2056" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::Restore on withdrawn window") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ( "/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2056" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::Restore on withdrawn window" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::Restore on withdrawn window"; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2056" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
2057 | return; | |||
2058 | } | |||
2059 | ||||
2060 | if( SHOWSTATE_MINIMIZED0 == nShowState_ ) | |||
2061 | { | |||
2062 | GetDisplay()->getWMAdaptor()->frameIsMapping( this ); | |||
2063 | XMapWindow( GetXDisplay(), GetShellWindow() ); | |||
2064 | nShowState_ = SHOWSTATE_NORMAL1; | |||
2065 | } | |||
2066 | ||||
2067 | pDisplay_->getWMAdaptor()->maximizeFrame( this, false, false ); | |||
2068 | } | |||
2069 | ||||
2070 | void X11SalFrame::SetScreenNumber( unsigned int nNewScreen ) | |||
2071 | { | |||
2072 | if( nNewScreen == maGeometry.nDisplayScreenNumber ) | |||
2073 | return; | |||
2074 | ||||
2075 | if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 ) | |||
2076 | { | |||
2077 | if( nNewScreen >= GetDisplay()->GetXineramaScreens().size() ) | |||
2078 | return; | |||
2079 | ||||
2080 | tools::Rectangle aOldScreenRect( GetDisplay()->GetXineramaScreens()[maGeometry.nDisplayScreenNumber] ); | |||
2081 | tools::Rectangle aNewScreenRect( GetDisplay()->GetXineramaScreens()[nNewScreen] ); | |||
2082 | bool bVisible = bMapped_; | |||
2083 | if( bVisible ) | |||
2084 | Show( false ); | |||
2085 | maGeometry.nX = aNewScreenRect.Left() + (maGeometry.nX - aOldScreenRect.Left()); | |||
2086 | maGeometry.nY = aNewScreenRect.Top() + (maGeometry.nY - aOldScreenRect.Top()); | |||
2087 | createNewWindow( None0L, m_nXScreen ); | |||
2088 | if( bVisible ) | |||
2089 | Show( true ); | |||
2090 | maGeometry.nDisplayScreenNumber = nNewScreen; | |||
2091 | } | |||
2092 | else if( nNewScreen < GetDisplay()->GetXScreenCount() ) | |||
2093 | { | |||
2094 | bool bVisible = bMapped_; | |||
2095 | if( bVisible ) | |||
2096 | Show( false ); | |||
2097 | createNewWindow( None0L, SalX11Screen( nNewScreen ) ); | |||
2098 | if( bVisible ) | |||
2099 | Show( true ); | |||
2100 | maGeometry.nDisplayScreenNumber = nNewScreen; | |||
2101 | } | |||
2102 | } | |||
2103 | ||||
2104 | void X11SalFrame::SetApplicationID( const OUString &rWMClass ) | |||
2105 | { | |||
2106 | if( rWMClass != m_sWMClass && ! IsChildWindow() ) | |||
2107 | { | |||
2108 | m_sWMClass = rWMClass; | |||
2109 | updateWMClass(); | |||
2110 | for (auto const& child : maChildren) | |||
2111 | child->SetApplicationID(rWMClass); | |||
2112 | } | |||
2113 | } | |||
2114 | ||||
2115 | void X11SalFrame::updateWMClass() | |||
2116 | { | |||
2117 | XClassHint* pClass = XAllocClassHint(); | |||
2118 | OString aResName = SalGenericSystem::getFrameResName(); | |||
2119 | pClass->res_name = const_cast<char*>(aResName.getStr()); | |||
2120 | ||||
2121 | OString aResClass = OUStringToOString(m_sWMClass, RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11))); | |||
2122 | const char *pResClass = !aResClass.isEmpty() ? aResClass.getStr() : | |||
2123 | SalGenericSystem::getFrameClassName(); | |||
2124 | ||||
2125 | pClass->res_class = const_cast<char*>(pResClass); | |||
2126 | XSetClassHint( GetXDisplay(), GetShellWindow(), pClass ); | |||
2127 | XFree( pClass ); | |||
2128 | } | |||
2129 | ||||
2130 | void X11SalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nScreen ) | |||
2131 | { | |||
2132 | if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 ) | |||
2133 | { | |||
2134 | if( mbFullScreen == bFullScreen ) | |||
2135 | return; | |||
2136 | if( bFullScreen ) | |||
2137 | { | |||
2138 | maRestorePosSize = tools::Rectangle( Point( maGeometry.nX, maGeometry.nY ), | |||
2139 | Size( maGeometry.nWidth, maGeometry.nHeight ) ); | |||
2140 | tools::Rectangle aRect; | |||
2141 | if( nScreen < 0 || nScreen >= static_cast<int>(GetDisplay()->GetXineramaScreens().size()) ) | |||
2142 | aRect = tools::Rectangle( Point(0,0), GetDisplay()->GetScreenSize( m_nXScreen ) ); | |||
2143 | else | |||
2144 | aRect = GetDisplay()->GetXineramaScreens()[nScreen]; | |||
2145 | nStyle_ |= SalFrameStyleFlags::PARTIAL_FULLSCREEN; | |||
2146 | bool bVisible = bMapped_; | |||
2147 | if( bVisible ) | |||
2148 | Show( false ); | |||
2149 | maGeometry.nX = aRect.Left(); | |||
2150 | maGeometry.nY = aRect.Top(); | |||
2151 | maGeometry.nWidth = aRect.GetWidth(); | |||
2152 | maGeometry.nHeight = aRect.GetHeight(); | |||
2153 | mbMaximizedHorz = mbMaximizedVert = false; | |||
2154 | mbFullScreen = true; | |||
2155 | createNewWindow( None0L, m_nXScreen ); | |||
2156 | if( GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) | |||
2157 | GetDisplay()->getWMAdaptor()->enableAlwaysOnTop( this, true ); | |||
2158 | else | |||
2159 | GetDisplay()->getWMAdaptor()->showFullScreen( this, true ); | |||
2160 | if( bVisible ) | |||
2161 | Show(true); | |||
2162 | ||||
2163 | } | |||
2164 | else | |||
2165 | { | |||
2166 | mbFullScreen = false; | |||
2167 | nStyle_ &= ~SalFrameStyleFlags::PARTIAL_FULLSCREEN; | |||
2168 | bool bVisible = bMapped_; | |||
2169 | tools::Rectangle aRect = maRestorePosSize; | |||
2170 | maRestorePosSize = tools::Rectangle(); | |||
2171 | if( bVisible ) | |||
2172 | Show( false ); | |||
2173 | createNewWindow( None0L, m_nXScreen ); | |||
2174 | if( !aRect.IsEmpty() ) | |||
2175 | SetPosSize( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), | |||
2176 | SAL_FRAME_POSSIZE_X(sal_uInt16(0x0001)) | SAL_FRAME_POSSIZE_Y(sal_uInt16(0x0002)) | | |||
2177 | SAL_FRAME_POSSIZE_WIDTH(sal_uInt16(0x0004)) | SAL_FRAME_POSSIZE_HEIGHT(sal_uInt16(0x0008)) ); | |||
2178 | if( bVisible ) | |||
2179 | Show( true ); | |||
2180 | } | |||
2181 | } | |||
2182 | else | |||
2183 | { | |||
2184 | if( nScreen < 0 || nScreen >= static_cast<int>(GetDisplay()->GetXScreenCount()) ) | |||
2185 | nScreen = m_nXScreen.getXScreen(); | |||
2186 | if( nScreen != static_cast<int>(m_nXScreen.getXScreen()) ) | |||
2187 | { | |||
2188 | bool bVisible = bMapped_; | |||
2189 | if( mbFullScreen ) | |||
2190 | pDisplay_->getWMAdaptor()->showFullScreen( this, false ); | |||
2191 | if( bVisible ) | |||
2192 | Show( false ); | |||
2193 | createNewWindow( None0L, SalX11Screen( nScreen ) ); | |||
2194 | if( mbFullScreen ) | |||
2195 | pDisplay_->getWMAdaptor()->showFullScreen( this, true ); | |||
2196 | if( bVisible ) | |||
2197 | Show( true ); | |||
2198 | } | |||
2199 | if( mbFullScreen == bFullScreen ) | |||
2200 | return; | |||
2201 | ||||
2202 | pDisplay_->getWMAdaptor()->showFullScreen( this, bFullScreen ); | |||
2203 | } | |||
2204 | } | |||
2205 | ||||
2206 | void X11SalFrame::StartPresentation( bool bStart ) | |||
2207 | { | |||
2208 | maScreenSaverInhibitor.inhibit( bStart, | |||
2209 | "presentation", | |||
2210 | true, // isX11 | |||
2211 | mhWindow, | |||
2212 | GetXDisplay() ); | |||
2213 | ||||
2214 | if( ! bStart && hPresentationWindow != None0L ) | |||
2215 | doReparentPresentationDialogues( GetDisplay() ); | |||
2216 | hPresentationWindow = (bStart && IsOverrideRedirect() ) ? GetWindow() : None0L; | |||
2217 | ||||
2218 | if( bStart && hPresentationWindow ) | |||
2219 | { | |||
2220 | /* #i10559# workaround for WindowMaker: try to restore | |||
2221 | * current focus after presentation window is gone | |||
2222 | */ | |||
2223 | int revert_to = 0; | |||
2224 | XGetInputFocus( GetXDisplay(), &hPresFocusWindow, &revert_to ); | |||
2225 | } | |||
2226 | } | |||
2227 | ||||
2228 | // Pointer | |||
2229 | ||||
2230 | void X11SalFrame::SetPointer( PointerStyle ePointerStyle ) | |||
2231 | { | |||
2232 | hCursor_ = pDisplay_->GetPointer( ePointerStyle ); | |||
2233 | XDefineCursor( GetXDisplay(), GetWindow(), hCursor_ ); | |||
2234 | ||||
2235 | if( IsCaptured() || nVisibleFloats > 0 ) | |||
2236 | XChangeActivePointerGrab( GetXDisplay(), | |||
2237 | PointerMotionMask(1L<<6)|ButtonPressMask(1L<<2)|ButtonReleaseMask(1L<<3), | |||
2238 | hCursor_, | |||
2239 | CurrentTime0L ); | |||
2240 | } | |||
2241 | ||||
2242 | void X11SalFrame::SetPointerPos(long nX, long nY) | |||
2243 | { | |||
2244 | /* when the application tries to center the mouse in the dialog the | |||
2245 | * window isn't mapped already. So use coordinates relative to the root window. | |||
2246 | */ | |||
2247 | unsigned int nWindowLeft = maGeometry.nX + nX; | |||
2248 | unsigned int nWindowTop = maGeometry.nY + nY; | |||
2249 | ||||
2250 | XWarpPointer( GetXDisplay(), None0L, pDisplay_->GetRootWindow( pDisplay_->GetDefaultXScreen() ), | |||
2251 | 0, 0, 0, 0, nWindowLeft, nWindowTop); | |||
2252 | } | |||
2253 | ||||
2254 | // delay handling of extended text input | |||
2255 | #if !defined(__synchronous_extinput__) | |||
2256 | void | |||
2257 | X11SalFrame::HandleExtTextEvent (XClientMessageEvent const *pEvent) | |||
2258 | { | |||
2259 | #if SAL_TYPES_SIZEOFLONG8 > 4 | |||
2260 | void* pExtTextEvent = reinterpret_cast<void*>( (pEvent->data.l[0] & 0xffffffff) | |||
2261 | | (pEvent->data.l[1] << 32) ); | |||
2262 | #else | |||
2263 | void* pExtTextEvent = reinterpret_cast<void*>(pEvent->data.l[0]); | |||
2264 | #endif | |||
2265 | SalEvent nExtTextEventType = SalEvent(pEvent->data.l[2]); | |||
2266 | ||||
2267 | CallCallback(nExtTextEventType, pExtTextEvent); | |||
2268 | ||||
2269 | switch (nExtTextEventType) | |||
2270 | { | |||
2271 | case SalEvent::EndExtTextInput: | |||
2272 | break; | |||
2273 | ||||
2274 | case SalEvent::ExtTextInput: | |||
2275 | break; | |||
2276 | ||||
2277 | default: | |||
2278 | SAL_WARN("vcl.window",do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "X11SalFrame::HandleExtTextEvent: invalid extended input." ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2279" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::HandleExtTextEvent: invalid extended input." ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::HandleExtTextEvent: invalid extended input." ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2279" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::HandleExtTextEvent: invalid extended input." ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2279" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::HandleExtTextEvent: invalid extended input." ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::HandleExtTextEvent: invalid extended input." ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2279" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
2279 | "X11SalFrame::HandleExtTextEvent: invalid extended input.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "X11SalFrame::HandleExtTextEvent: invalid extended input." ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2279" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::HandleExtTextEvent: invalid extended input." ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::HandleExtTextEvent: invalid extended input." ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2279" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::HandleExtTextEvent: invalid extended input." ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2279" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::HandleExtTextEvent: invalid extended input." ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::HandleExtTextEvent: invalid extended input." ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "2279" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
2280 | } | |||
2281 | } | |||
2282 | #endif /* defined(__synchronous_extinput__) */ | |||
2283 | ||||
2284 | // PostEvent | |||
2285 | ||||
2286 | bool X11SalFrame::PostEvent(std::unique_ptr<ImplSVEvent> pData) | |||
2287 | { | |||
2288 | GetDisplay()->SendInternalEvent( this, pData.release() ); | |||
2289 | return true; | |||
2290 | } | |||
2291 | ||||
2292 | // Title | |||
2293 | ||||
2294 | void X11SalFrame::SetTitle( const OUString& rTitle ) | |||
2295 | { | |||
2296 | if( ! ( IsChildWindow() || (nStyle_ & SalFrameStyleFlags::FLOAT ) ) ) | |||
2297 | { | |||
2298 | m_aTitle = rTitle; | |||
2299 | GetDisplay()->getWMAdaptor()->setWMName( this, rTitle ); | |||
2300 | } | |||
2301 | } | |||
2302 | ||||
2303 | void X11SalFrame::Flush() | |||
2304 | { | |||
2305 | if( pGraphics_ ) | |||
2306 | pGraphics_->Flush(); | |||
2307 | XFlush( GetDisplay()->GetDisplay() ); | |||
2308 | } | |||
2309 | ||||
2310 | // Keyboard | |||
2311 | ||||
2312 | void X11SalFrame::SetInputContext( SalInputContext* pContext ) | |||
2313 | { | |||
2314 | if (pContext == nullptr) | |||
2315 | return; | |||
2316 | ||||
2317 | // 1. We should create an input context for this frame | |||
2318 | // only when InputContextFlags::Text is set. | |||
2319 | ||||
2320 | if (!(pContext->mnOptions & InputContextFlags::Text)) | |||
2321 | { | |||
2322 | if( mpInputContext ) | |||
2323 | mpInputContext->Unmap(); | |||
2324 | return; | |||
2325 | } | |||
2326 | ||||
2327 | // 2. We should use on-the-spot inputstyle | |||
2328 | // only when InputContextFlags::ExtTExt is set. | |||
2329 | ||||
2330 | if (mpInputContext == nullptr) | |||
2331 | { | |||
2332 | mpInputContext.reset( new SalI18N_InputContext( this ) ); | |||
2333 | if (mpInputContext->UseContext()) | |||
2334 | { | |||
2335 | mpInputContext->ExtendEventMask( GetShellWindow() ); | |||
2336 | if (mbInputFocus) | |||
2337 | mpInputContext->SetICFocus( this ); | |||
2338 | } | |||
2339 | } | |||
2340 | else | |||
2341 | mpInputContext->Map( this ); | |||
2342 | } | |||
2343 | ||||
2344 | void X11SalFrame::EndExtTextInput( EndExtTextInputFlags ) | |||
2345 | { | |||
2346 | if (mpInputContext != nullptr) | |||
2347 | mpInputContext->EndExtTextInput(); | |||
2348 | } | |||
2349 | ||||
2350 | OUString X11SalFrame::GetKeyName( sal_uInt16 nKeyCode ) | |||
2351 | { | |||
2352 | return GetDisplay()->GetKeyName( nKeyCode ); | |||
2353 | } | |||
2354 | ||||
2355 | bool X11SalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , vcl::KeyCode& ) | |||
2356 | { | |||
2357 | // not supported yet | |||
2358 | return false; | |||
2359 | } | |||
2360 | ||||
2361 | LanguageType X11SalFrame::GetInputLanguage() | |||
2362 | { | |||
2363 | // could be improved by checking unicode ranges of the last input | |||
2364 | return LANGUAGE_DONTKNOWLanguageType(0x03FF); | |||
2365 | } | |||
2366 | ||||
2367 | // Settings | |||
2368 | ||||
2369 | void X11SalFrame::UpdateSettings( AllSettings& rSettings ) | |||
2370 | { | |||
2371 | StyleSettings aStyleSettings = rSettings.GetStyleSettings(); | |||
2372 | aStyleSettings.SetCursorBlinkTime( 500 ); | |||
2373 | aStyleSettings.SetMenuBarTextColor( aStyleSettings.GetPersonaMenuBarTextColor().value_or( COL_BLACK ) ); | |||
2374 | rSettings.SetStyleSettings( aStyleSettings ); | |||
2375 | } | |||
2376 | ||||
2377 | void X11SalFrame::CaptureMouse( bool bCapture ) | |||
2378 | { | |||
2379 | nCaptured_ = pDisplay_->CaptureMouse( bCapture ? this : nullptr ); | |||
2380 | } | |||
2381 | ||||
2382 | void X11SalFrame::SetParent( SalFrame* pNewParent ) | |||
2383 | { | |||
2384 | if( mpParent != pNewParent
| |||
2385 | { | |||
2386 | if( mpParent
| |||
2387 | mpParent->maChildren.remove( this ); | |||
2388 | ||||
2389 | mpParent = static_cast<X11SalFrame*>(pNewParent); | |||
2390 | mpParent->maChildren.push_back( this ); | |||
| ||||
2391 | if( mpParent->m_nXScreen != m_nXScreen ) | |||
2392 | createNewWindow( None0L, mpParent->m_nXScreen ); | |||
2393 | GetDisplay()->getWMAdaptor()->changeReferenceFrame( this, mpParent ); | |||
2394 | } | |||
2395 | } | |||
2396 | ||||
2397 | SalFrame* X11SalFrame::GetParent() const | |||
2398 | { | |||
2399 | return mpParent; | |||
2400 | } | |||
2401 | ||||
2402 | void X11SalFrame::createNewWindow( ::Window aNewParent, SalX11Screen nXScreen ) | |||
2403 | { | |||
2404 | bool bWasVisible = bMapped_; | |||
2405 | if( bWasVisible ) | |||
2406 | Show( false ); | |||
2407 | ||||
2408 | if( nXScreen.getXScreen() >= GetDisplay()->GetXScreenCount() ) | |||
2409 | nXScreen = m_nXScreen; | |||
2410 | ||||
2411 | SystemParentData aParentData; | |||
2412 | aParentData.nSize = sizeof(SystemParentData); | |||
2413 | aParentData.aWindow = aNewParent; | |||
2414 | aParentData.bXEmbedSupport = (aNewParent != None0L && m_bXEmbed); // caution: this is guesswork | |||
2415 | if( aNewParent
| |||
2416 | { | |||
2417 | aParentData.aWindow = None0L; | |||
2418 | m_bXEmbed = false; | |||
2419 | } | |||
2420 | else | |||
2421 | { | |||
2422 | // is new parent a root window ? | |||
2423 | Display* pDisp = GetDisplay()->GetDisplay(); | |||
2424 | int nScreens = GetDisplay()->GetXScreenCount(); | |||
2425 | for( int i = 0; i < nScreens; i++ ) | |||
2426 | { | |||
2427 | if( aNewParent == RootWindow( pDisp, i )((&((_XPrivDisplay)(pDisp))->screens[i])->root) ) | |||
2428 | { | |||
2429 | nXScreen = SalX11Screen( i ); | |||
2430 | aParentData.aWindow = None0L; | |||
2431 | m_bXEmbed = false; | |||
2432 | break; | |||
2433 | } | |||
2434 | } | |||
2435 | } | |||
2436 | ||||
2437 | // first deinit frame | |||
2438 | updateGraphics(true); | |||
2439 | if( mpInputContext ) | |||
2440 | { | |||
2441 | mpInputContext->UnsetICFocus(); | |||
2442 | mpInputContext->Unmap(); | |||
2443 | } | |||
2444 | if( GetWindow() == hPresentationWindow ) | |||
2445 | { | |||
2446 | hPresentationWindow = None0L; | |||
2447 | doReparentPresentationDialogues( GetDisplay() ); | |||
2448 | } | |||
2449 | XDestroyWindow( GetXDisplay(), mhWindow ); | |||
2450 | mhWindow = None0L; | |||
2451 | ||||
2452 | // now init with new parent again | |||
2453 | if ( aParentData.aWindow
| |||
2454 | Init( nStyle_ | SalFrameStyleFlags::PLUG, nXScreen, &aParentData ); | |||
2455 | else | |||
2456 | Init( nStyle_ & ~SalFrameStyleFlags::PLUG, nXScreen, nullptr, true ); | |||
2457 | ||||
2458 | // update graphics if necessary | |||
2459 | updateGraphics(false); | |||
2460 | ||||
2461 | if( ! m_aTitle.isEmpty() ) | |||
2462 | SetTitle( m_aTitle ); | |||
2463 | ||||
2464 | if( mpParent ) | |||
2465 | { | |||
2466 | if( mpParent->m_nXScreen != m_nXScreen ) | |||
2467 | SetParent( nullptr ); | |||
2468 | else | |||
2469 | pDisplay_->getWMAdaptor()->changeReferenceFrame( this, mpParent ); | |||
2470 | } | |||
2471 | ||||
2472 | if( bWasVisible ) | |||
2473 | Show( true ); | |||
2474 | ||||
2475 | std::list< X11SalFrame* > aChildren = maChildren; | |||
2476 | for (auto const& child : aChildren) | |||
2477 | child->createNewWindow( None0L, m_nXScreen ); | |||
2478 | ||||
2479 | // FIXME: SalObjects | |||
2480 | } | |||
2481 | ||||
2482 | bool X11SalFrame::SetPluginParent( SystemParentData* pNewParent ) | |||
2483 | { | |||
2484 | if( pNewParent->nSize >= sizeof(SystemParentData) ) | |||
| ||||
2485 | m_bXEmbed = pNewParent->aWindow != None0L && pNewParent->bXEmbedSupport; | |||
2486 | ||||
2487 | createNewWindow(pNewParent->aWindow); | |||
2488 | ||||
2489 | return true; | |||
2490 | } | |||
2491 | ||||
2492 | // Sound | |||
2493 | void X11SalFrame::Beep() | |||
2494 | { | |||
2495 | GetDisplay()->Beep(); | |||
2496 | } | |||
2497 | ||||
2498 | // Event Handling | |||
2499 | ||||
2500 | static sal_uInt16 sal_GetCode( int state ) | |||
2501 | { | |||
2502 | sal_uInt16 nCode = 0; | |||
2503 | ||||
2504 | if( state & Button1Mask(1<<8) ) | |||
2505 | nCode |= MOUSE_LEFT(sal_uInt16(0x0001)); | |||
2506 | if( state & Button2Mask(1<<9) ) | |||
2507 | nCode |= MOUSE_MIDDLE(sal_uInt16(0x0002)); | |||
2508 | if( state & Button3Mask(1<<10) ) | |||
2509 | nCode |= MOUSE_RIGHT(sal_uInt16(0x0004)); | |||
2510 | ||||
2511 | if( state & ShiftMask(1<<0) ) | |||
2512 | nCode |= KEY_SHIFT; | |||
2513 | if( state & ControlMask(1<<2) ) | |||
2514 | nCode |= KEY_MOD1; | |||
2515 | if( state & Mod1Mask(1<<3) ) | |||
2516 | nCode |= KEY_MOD2; | |||
2517 | ||||
2518 | // Map Meta/Super modifier to MOD3 on all Unix systems | |||
2519 | // except macOS | |||
2520 | if( state & Mod3Mask(1<<5) ) | |||
2521 | nCode |= KEY_MOD3; | |||
2522 | ||||
2523 | return nCode; | |||
2524 | } | |||
2525 | ||||
2526 | SalFrame::SalPointerState X11SalFrame::GetPointerState() | |||
2527 | { | |||
2528 | SalPointerState aState; | |||
2529 | ::Window aRoot, aChild; | |||
2530 | int rx, ry, wx, wy; | |||
2531 | unsigned int nMask = 0; | |||
2532 | XQueryPointer( GetXDisplay(), | |||
2533 | GetShellWindow(), | |||
2534 | &aRoot, | |||
2535 | &aChild, | |||
2536 | &rx, &ry, | |||
2537 | &wx, &wy, | |||
2538 | &nMask | |||
2539 | ); | |||
2540 | ||||
2541 | aState.maPos = Point(wx, wy); | |||
2542 | aState.mnState = sal_GetCode( nMask ); | |||
2543 | return aState; | |||
2544 | } | |||
2545 | ||||
2546 | KeyIndicatorState X11SalFrame::GetIndicatorState() | |||
2547 | { | |||
2548 | return vcl_sal::getSalDisplay(GetGenericUnixSalData())->GetIndicatorState(); | |||
2549 | } | |||
2550 | ||||
2551 | void X11SalFrame::SimulateKeyPress( sal_uInt16 nKeyCode ) | |||
2552 | { | |||
2553 | vcl_sal::getSalDisplay(GetGenericUnixSalData())->SimulateKeyPress(nKeyCode); | |||
2554 | } | |||
2555 | ||||
2556 | namespace | |||
2557 | { | |||
2558 | struct CompressWheelEventsData | |||
2559 | { | |||
2560 | XEvent* firstEvent; | |||
2561 | bool ignore; | |||
2562 | int count; // number of compressed events | |||
2563 | }; | |||
2564 | ||||
2565 | Boolint compressWheelEvents( Display*, XEvent* event, XPointer p ) | |||
2566 | { | |||
2567 | CompressWheelEventsData* data = reinterpret_cast< CompressWheelEventsData* >( p ); | |||
2568 | if( data->ignore ) | |||
2569 | return False0; // we're already after the events to compress | |||
2570 | if( event->type == ButtonPress4 || event->type == ButtonRelease5 ) | |||
2571 | { | |||
2572 | const unsigned int mask = Button1Mask(1<<8) << ( event->xbutton.button - Button11 ); | |||
2573 | if( event->xbutton.button == data->firstEvent->xbutton.button | |||
2574 | && event->xbutton.window == data->firstEvent->xbutton.window | |||
2575 | && event->xbutton.x == data->firstEvent->xbutton.x | |||
2576 | && event->xbutton.y == data->firstEvent->xbutton.y | |||
2577 | && ( event->xbutton.state | mask ) == ( data->firstEvent->xbutton.state | mask )) | |||
2578 | { | |||
2579 | // Count if it's another press (i.e. wheel start event). | |||
2580 | if( event->type == ButtonPress4 ) | |||
2581 | ++data->count; | |||
2582 | return True1; // And remove the event from the queue. | |||
2583 | } | |||
2584 | } | |||
2585 | // Non-matching event, skip certain events that cannot possibly affect input processing, | |||
2586 | // but otherwise ignore all further events. | |||
2587 | switch( event->type ) | |||
2588 | { | |||
2589 | case Expose12: | |||
2590 | case NoExpose14: | |||
2591 | break; | |||
2592 | default: | |||
2593 | data->ignore = true; | |||
2594 | break; | |||
2595 | } | |||
2596 | return False0; | |||
2597 | } | |||
2598 | ||||
2599 | } // namespace | |||
2600 | ||||
2601 | bool X11SalFrame::HandleMouseEvent( XEvent *pEvent ) | |||
2602 | { | |||
2603 | SalMouseEvent aMouseEvt; | |||
2604 | SalEvent nEvent = SalEvent::NONE; | |||
2605 | bool bClosePopups = false; | |||
2606 | ||||
2607 | if( nVisibleFloats && pEvent->type == EnterNotify7 ) | |||
2608 | return false; | |||
2609 | ||||
2610 | if( LeaveNotify8 == pEvent->type || EnterNotify7 == pEvent->type ) | |||
2611 | { | |||
2612 | /* | |||
2613 | * some WMs (and/or) applications have a passive grab on | |||
2614 | * mouse buttons (XGrabButton). This leads to enter/leave notifies | |||
2615 | * with mouse buttons pressed in the state mask before the actual | |||
2616 | * ButtonPress event gets dispatched. But EnterNotify | |||
2617 | * is reported in vcl as MouseMove event. Some office code | |||
2618 | * decides that a pressed button in a MouseMove belongs to | |||
2619 | * a drag operation which leads to doing things differently. | |||
2620 | * | |||
2621 | * ignore Enter/LeaveNotify resulting from grabs so that | |||
2622 | * help windows do not disappear just after appearing | |||
2623 | * | |||
2624 | * hopefully this workaround will not break anything. | |||
2625 | */ | |||
2626 | if( pEvent->xcrossing.mode == NotifyGrab1 || pEvent->xcrossing.mode == NotifyUngrab2 ) | |||
2627 | return false; | |||
2628 | ||||
2629 | aMouseEvt.mnX = pEvent->xcrossing.x; | |||
2630 | aMouseEvt.mnY = pEvent->xcrossing.y; | |||
2631 | aMouseEvt.mnTime = pEvent->xcrossing.time; | |||
2632 | aMouseEvt.mnCode = sal_GetCode( pEvent->xcrossing.state ); | |||
2633 | aMouseEvt.mnButton = 0; | |||
2634 | ||||
2635 | nEvent = LeaveNotify8 == pEvent->type | |||
2636 | ? SalEvent::MouseLeave | |||
2637 | : SalEvent::MouseMove; | |||
2638 | } | |||
2639 | else if( pEvent->type == MotionNotify6 ) | |||
2640 | { | |||
2641 | aMouseEvt.mnX = pEvent->xmotion.x; | |||
2642 | aMouseEvt.mnY = pEvent->xmotion.y; | |||
2643 | aMouseEvt.mnTime = pEvent->xmotion.time; | |||
2644 | aMouseEvt.mnCode = sal_GetCode( pEvent->xmotion.state ); | |||
2645 | ||||
2646 | aMouseEvt.mnButton = 0; | |||
2647 | ||||
2648 | nEvent = SalEvent::MouseMove; | |||
2649 | if( nVisibleFloats > 0 && mpParent ) | |||
2650 | { | |||
2651 | Cursor aCursor = mpParent->GetCursor(); | |||
2652 | if( pEvent->xmotion.x >= 0 && pEvent->xmotion.x < static_cast<int>(maGeometry.nWidth) && | |||
2653 | pEvent->xmotion.y >= 0 && pEvent->xmotion.y < static_cast<int>(maGeometry.nHeight) ) | |||
2654 | aCursor = None0L; | |||
2655 | ||||
2656 | XChangeActivePointerGrab( GetXDisplay(), | |||
2657 | PointerMotionMask(1L<<6)|ButtonPressMask(1L<<2)|ButtonReleaseMask(1L<<3), | |||
2658 | aCursor, | |||
2659 | CurrentTime0L ); | |||
2660 | } | |||
2661 | } | |||
2662 | else | |||
2663 | { | |||
2664 | // let mouse events reach the correct window | |||
2665 | if( nVisibleFloats < 1 ) | |||
2666 | { | |||
2667 | if( ! (nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ) | |||
2668 | XUngrabPointer( GetXDisplay(), CurrentTime0L ); | |||
2669 | } | |||
2670 | else if( pEvent->type == ButtonPress4 ) | |||
2671 | { | |||
2672 | // see if the user clicks outside all of the floats | |||
2673 | // if yes release the grab | |||
2674 | bool bInside = false; | |||
2675 | for (auto pSalFrame : GetDisplay()->getFrames() ) | |||
2676 | { | |||
2677 | const X11SalFrame* pFrame = static_cast< const X11SalFrame* >( pSalFrame ); | |||
2678 | if( pFrame->IsFloatGrabWindow() && | |||
2679 | pFrame->bMapped_ && | |||
2680 | pEvent->xbutton.x_root >= pFrame->maGeometry.nX && | |||
2681 | pEvent->xbutton.x_root < pFrame->maGeometry.nX + static_cast<int>(pFrame->maGeometry.nWidth) && | |||
2682 | pEvent->xbutton.y_root >= pFrame->maGeometry.nY && | |||
2683 | pEvent->xbutton.y_root < pFrame->maGeometry.nY + static_cast<int>(pFrame->maGeometry.nHeight) ) | |||
2684 | { | |||
2685 | bInside = true; | |||
2686 | break; | |||
2687 | } | |||
2688 | } | |||
2689 | if( ! bInside ) | |||
2690 | { | |||
2691 | // need not take care of the XUngrabPointer in Show( false ) | |||
2692 | // because XUngrabPointer does not produce errors if pointer | |||
2693 | // is not grabbed | |||
2694 | XUngrabPointer( GetXDisplay(), CurrentTime0L ); | |||
2695 | bClosePopups = true; | |||
2696 | ||||
2697 | /* #i15246# only close popups if pointer is outside all our frames | |||
2698 | * cannot use our own geometry data here because stacking | |||
2699 | * is unknown (the above case implicitly assumes | |||
2700 | * that floats are on top which should be true) | |||
2701 | */ | |||
2702 | ::Window aRoot, aChild; | |||
2703 | int root_x, root_y, win_x, win_y; | |||
2704 | unsigned int mask_return; | |||
2705 | if( XQueryPointer( GetXDisplay(), | |||
2706 | GetDisplay()->GetRootWindow( m_nXScreen ), | |||
2707 | &aRoot, &aChild, | |||
2708 | &root_x, &root_y, | |||
2709 | &win_x, &win_y, | |||
2710 | &mask_return ) | |||
2711 | && aChild // pointer may not be in any child | |||
2712 | ) | |||
2713 | { | |||
2714 | for (auto pSalFrame : GetDisplay()->getFrames() ) | |||
2715 | { | |||
2716 | const X11SalFrame* pFrame = static_cast< const X11SalFrame* >( pSalFrame ); | |||
2717 | if( ! pFrame->IsFloatGrabWindow() | |||
2718 | && ( pFrame->GetWindow() == aChild || | |||
2719 | pFrame->GetShellWindow() == aChild || | |||
2720 | pFrame->GetStackingWindow() == aChild ) | |||
2721 | ) | |||
2722 | { | |||
2723 | // #i63638# check that pointer is inside window, not | |||
2724 | // only inside stacking window | |||
2725 | if( root_x >= pFrame->maGeometry.nX && root_x < sal::static_int_cast< int >(pFrame->maGeometry.nX+pFrame->maGeometry.nWidth) && | |||
2726 | root_y >= pFrame->maGeometry.nY && root_y < sal::static_int_cast< int >(pFrame->maGeometry.nX+pFrame->maGeometry.nHeight) ) | |||
2727 | { | |||
2728 | bClosePopups = false; | |||
2729 | } | |||
2730 | break; | |||
2731 | } | |||
2732 | } | |||
2733 | } | |||
2734 | } | |||
2735 | } | |||
2736 | ||||
2737 | if( m_bXEmbed && pEvent->xbutton.button == Button11 ) | |||
2738 | askForXEmbedFocus( pEvent->xbutton.time ); | |||
2739 | ||||
2740 | if( pEvent->xbutton.button == Button11 || | |||
2741 | pEvent->xbutton.button == Button22 || | |||
2742 | pEvent->xbutton.button == Button33 ) | |||
2743 | { | |||
2744 | aMouseEvt.mnX = pEvent->xbutton.x; | |||
2745 | aMouseEvt.mnY = pEvent->xbutton.y; | |||
2746 | aMouseEvt.mnTime = pEvent->xbutton.time; | |||
2747 | aMouseEvt.mnCode = sal_GetCode( pEvent->xbutton.state ); | |||
2748 | ||||
2749 | if( Button11 == pEvent->xbutton.button ) | |||
2750 | aMouseEvt.mnButton = MOUSE_LEFT(sal_uInt16(0x0001)); | |||
2751 | else if( Button22 == pEvent->xbutton.button ) | |||
2752 | aMouseEvt.mnButton = MOUSE_MIDDLE(sal_uInt16(0x0002)); | |||
2753 | else if( Button33 == pEvent->xbutton.button ) | |||
2754 | aMouseEvt.mnButton = MOUSE_RIGHT(sal_uInt16(0x0004)); | |||
2755 | ||||
2756 | nEvent = ButtonPress4 == pEvent->type | |||
2757 | ? SalEvent::MouseButtonDown | |||
2758 | : SalEvent::MouseButtonUp; | |||
2759 | } | |||
2760 | else if( pEvent->xbutton.button == Button44 || | |||
2761 | pEvent->xbutton.button == Button55 || | |||
2762 | pEvent->xbutton.button == Button66 || | |||
2763 | pEvent->xbutton.button == Button77 ) | |||
2764 | { | |||
2765 | const bool bIncrement( | |||
2766 | pEvent->xbutton.button == Button44 || | |||
2767 | pEvent->xbutton.button == Button66 ); | |||
2768 | const bool bHoriz( | |||
2769 | pEvent->xbutton.button == Button66 || | |||
2770 | pEvent->xbutton.button == Button77 ); | |||
2771 | ||||
2772 | if( pEvent->type == ButtonRelease5 ) | |||
2773 | return false; | |||
2774 | ||||
2775 | static sal_uLong nLines = 0; | |||
2776 | if( ! nLines ) | |||
2777 | { | |||
2778 | char* pEnv = getenv( "SAL_WHEELLINES" ); | |||
2779 | nLines = pEnv ? atoi( pEnv ) : 3; | |||
2780 | if( nLines > 10 ) | |||
2781 | nLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL(sal_uLong(0xFFFFFFFF)); | |||
2782 | } | |||
2783 | ||||
2784 | // Compress consecutive wheel events (way too fine scrolling may cause lags if one scrolling steps takes long). | |||
2785 | CompressWheelEventsData data; | |||
2786 | data.firstEvent = pEvent; | |||
2787 | data.count = 1; | |||
2788 | XEvent dummy; | |||
2789 | do | |||
2790 | { | |||
2791 | data.ignore = false; | |||
2792 | } while( XCheckIfEvent( pEvent->xany.display, &dummy, compressWheelEvents, reinterpret_cast< XPointer >( &data ))); | |||
2793 | ||||
2794 | SalWheelMouseEvent aWheelEvt; | |||
2795 | aWheelEvt.mnTime = pEvent->xbutton.time; | |||
2796 | aWheelEvt.mnX = pEvent->xbutton.x; | |||
2797 | aWheelEvt.mnY = pEvent->xbutton.y; | |||
2798 | aWheelEvt.mnDelta = ( bIncrement ? 120 : -120 ) * data.count; | |||
2799 | aWheelEvt.mnNotchDelta = bIncrement ? 1 : -1; | |||
2800 | aWheelEvt.mnScrollLines = nLines * data.count; | |||
2801 | aWheelEvt.mnCode = sal_GetCode( pEvent->xbutton.state ); | |||
2802 | aWheelEvt.mbHorz = bHoriz; | |||
2803 | ||||
2804 | nEvent = SalEvent::WheelMouse; | |||
2805 | ||||
2806 | if( AllSettings::GetLayoutRTL() ) | |||
2807 | aWheelEvt.mnX = nWidth_-1-aWheelEvt.mnX; | |||
2808 | return CallCallback( nEvent, &aWheelEvt ); | |||
2809 | } | |||
2810 | } | |||
2811 | ||||
2812 | bool nRet = false; | |||
2813 | if( nEvent == SalEvent::MouseLeave | |||
2814 | || ( aMouseEvt.mnX < nWidth_ && aMouseEvt.mnX > -1 && | |||
2815 | aMouseEvt.mnY < nHeight_ && aMouseEvt.mnY > -1 ) | |||
2816 | || pDisplay_->MouseCaptured( this ) | |||
2817 | ) | |||
2818 | { | |||
2819 | if( AllSettings::GetLayoutRTL() ) | |||
2820 | aMouseEvt.mnX = nWidth_-1-aMouseEvt.mnX; | |||
2821 | nRet = CallCallback( nEvent, &aMouseEvt ); | |||
2822 | } | |||
2823 | ||||
2824 | if( bClosePopups ) | |||
2825 | { | |||
2826 | /* #108213# close popups after dispatching the event outside the popup; | |||
2827 | * applications do weird things. | |||
2828 | */ | |||
2829 | ImplSVData* pSVData = ImplGetSVData(); | |||
2830 | if (pSVData->mpWinData->mpFirstFloat) | |||
2831 | { | |||
2832 | if (!(pSVData->mpWinData->mpFirstFloat->GetPopupModeFlags() | |||
2833 | & FloatWinPopupFlags::NoAppFocusClose)) | |||
2834 | pSVData->mpWinData->mpFirstFloat->EndPopupMode(FloatWinPopupEndFlags::Cancel | |||
2835 | | FloatWinPopupEndFlags::CloseAll); | |||
2836 | } | |||
2837 | } | |||
2838 | ||||
2839 | return nRet; | |||
2840 | } | |||
2841 | ||||
2842 | namespace { | |||
2843 | ||||
2844 | // F10 means either KEY_F10 or KEY_MENU, which has to be decided | |||
2845 | // in the independent part. | |||
2846 | struct KeyAlternate | |||
2847 | { | |||
2848 | sal_uInt16 nKeyCode; | |||
2849 | sal_Unicode nCharCode; | |||
2850 | KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {} | |||
2851 | KeyAlternate( sal_uInt16 nKey, sal_Unicode nChar = 0 ) : nKeyCode( nKey ), nCharCode( nChar ) {} | |||
2852 | }; | |||
2853 | ||||
2854 | } | |||
2855 | ||||
2856 | static KeyAlternate | |||
2857 | GetAlternateKeyCode( const sal_uInt16 nKeyCode ) | |||
2858 | { | |||
2859 | KeyAlternate aAlternate; | |||
2860 | ||||
2861 | switch( nKeyCode ) | |||
2862 | { | |||
2863 | case KEY_F10: aAlternate = KeyAlternate( KEY_MENU );break; | |||
2864 | case KEY_F24: aAlternate = KeyAlternate( KEY_SUBTRACT, '-' );break; | |||
2865 | } | |||
2866 | ||||
2867 | return aAlternate; | |||
2868 | } | |||
2869 | ||||
2870 | void X11SalFrame::beginUnicodeSequence() | |||
2871 | { | |||
2872 | OUString& rSeq( GetGenericUnixSalData()->GetUnicodeCommand() ); | |||
2873 | vcl::DeletionListener aDeleteWatch( this ); | |||
2874 | ||||
2875 | if( !rSeq.isEmpty() ) | |||
2876 | endUnicodeSequence(); | |||
2877 | ||||
2878 | rSeq = "u"; | |||
2879 | ||||
2880 | if( ! aDeleteWatch.isDeleted() ) | |||
2881 | { | |||
2882 | ExtTextInputAttr nTextAttr = ExtTextInputAttr::Underline; | |||
2883 | SalExtTextInputEvent aEv; | |||
2884 | aEv.maText = rSeq; | |||
2885 | aEv.mpTextAttr = &nTextAttr; | |||
2886 | aEv.mnCursorPos = 0; | |||
2887 | aEv.mnCursorFlags = 0; | |||
2888 | ||||
2889 | CallCallback(SalEvent::ExtTextInput, static_cast<void*>(&aEv)); | |||
2890 | } | |||
2891 | } | |||
2892 | ||||
2893 | bool X11SalFrame::appendUnicodeSequence( sal_Unicode c ) | |||
2894 | { | |||
2895 | bool bRet = false; | |||
2896 | OUString& rSeq( GetGenericUnixSalData()->GetUnicodeCommand() ); | |||
2897 | if( !rSeq.isEmpty() ) | |||
2898 | { | |||
2899 | // range check | |||
2900 | if( (c >= '0' && c <= '9') || | |||
2901 | (c >= 'a' && c <= 'f') || | |||
2902 | (c >= 'A' && c <= 'F') ) | |||
2903 | { | |||
2904 | rSeq += OUStringChar(c); | |||
2905 | std::vector<ExtTextInputAttr> attribs( rSeq.getLength(), ExtTextInputAttr::Underline ); | |||
2906 | ||||
2907 | SalExtTextInputEvent aEv; | |||
2908 | aEv.maText = rSeq; | |||
2909 | aEv.mpTextAttr = attribs.data(); | |||
2910 | aEv.mnCursorPos = 0; | |||
2911 | aEv.mnCursorFlags = 0; | |||
2912 | ||||
2913 | CallCallback(SalEvent::ExtTextInput, static_cast<void*>(&aEv)); | |||
2914 | bRet = true; | |||
2915 | } | |||
2916 | else | |||
2917 | bRet = endUnicodeSequence(); | |||
2918 | } | |||
2919 | else | |||
2920 | endUnicodeSequence(); | |||
2921 | return bRet; | |||
2922 | } | |||
2923 | ||||
2924 | bool X11SalFrame::endUnicodeSequence() | |||
2925 | { | |||
2926 | OUString& rSeq( GetGenericUnixSalData()->GetUnicodeCommand() ); | |||
2927 | ||||
2928 | vcl::DeletionListener aDeleteWatch( this ); | |||
2929 | if( rSeq.getLength() > 1 && rSeq.getLength() < 6 ) | |||
2930 | { | |||
2931 | // cut the "u" | |||
2932 | OUString aNumbers( rSeq.copy( 1 ) ); | |||
2933 | sal_uInt32 nValue = aNumbers.toUInt32( 16 ); | |||
2934 | if( nValue >= 32 ) | |||
2935 | { | |||
2936 | ExtTextInputAttr nTextAttr = ExtTextInputAttr::Underline; | |||
2937 | SalExtTextInputEvent aEv; | |||
2938 | aEv.maText = OUString( sal_Unicode(nValue) ); | |||
2939 | aEv.mpTextAttr = &nTextAttr; | |||
2940 | aEv.mnCursorPos = 0; | |||
2941 | aEv.mnCursorFlags = 0; | |||
2942 | CallCallback(SalEvent::ExtTextInput, static_cast<void*>(&aEv)); | |||
2943 | } | |||
2944 | } | |||
2945 | bool bWasInput = !rSeq.isEmpty(); | |||
2946 | rSeq.clear(); | |||
2947 | if( bWasInput && ! aDeleteWatch.isDeleted() ) | |||
2948 | CallCallback(SalEvent::EndExtTextInput, nullptr); | |||
2949 | return bWasInput; | |||
2950 | } | |||
2951 | ||||
2952 | bool X11SalFrame::HandleKeyEvent( XKeyEvent *pEvent ) | |||
2953 | { | |||
2954 | if( pEvent->type == KeyRelease3 ) | |||
2955 | { | |||
2956 | // Ignore autorepeat keyrelease events. If there is a series of keypress+keyrelease+keypress events | |||
2957 | // generated by holding down a key, and if these are from autorepeat (keyrelease and the following keypress | |||
2958 | // have the same timestamp), drop the autorepeat keyrelease event. Not exactly sure why this is done | |||
2959 | // (possibly hiding differences between platforms, or just making it more sensible, because technically | |||
2960 | // the key has not been released at all). | |||
2961 | bool ignore = false; | |||
2962 | // Discard queued excessive autorepeat events. | |||
2963 | // If the user presses and holds down a key, the autorepeating keypress events | |||
2964 | // may overload LO (e.g. if the key is PageDown and the LO cannot keep up scrolling). | |||
2965 | // Reduce the load by simply discarding such excessive events (so for a KeyRelease event, | |||
2966 | // check if it's followed by matching KeyPress+KeyRelease pair(s) and discard those). | |||
2967 | // This shouldn't have any negative effects - unlike with normal (non-autorepeat | |||
2968 | // events), the user is unlikely to rely on the exact number of resulting actions | |||
2969 | // (since autorepeat generates keypress events rather quickly and it's hard to estimate | |||
2970 | // how many exactly) and the idea should be just keeping the key pressed until something | |||
2971 | // happens (in which case more events that just lag LO shouldn't make a difference). | |||
2972 | Display* dpy = pEvent->display; | |||
2973 | XKeyEvent previousRelease = *pEvent; | |||
2974 | while( XPending( dpy )) | |||
2975 | { | |||
2976 | XEvent nextEvent1; | |||
2977 | bool discard1 = false; | |||
2978 | XNextEvent( dpy, &nextEvent1 ); | |||
2979 | if( nextEvent1.type == KeyPress2 && nextEvent1.xkey.time == previousRelease.time | |||
2980 | && !nextEvent1.xkey.send_event && nextEvent1.xkey.window == previousRelease.window | |||
2981 | && nextEvent1.xkey.state == previousRelease.state && nextEvent1.xkey.keycode == previousRelease.keycode ) | |||
2982 | { // This looks like another autorepeat keypress. | |||
2983 | ignore = true; | |||
2984 | if( XPending( dpy )) | |||
2985 | { | |||
2986 | XEvent nextEvent2; | |||
2987 | XNextEvent( dpy, &nextEvent2 ); | |||
2988 | if( nextEvent2.type == KeyRelease3 && nextEvent2.xkey.time <= ( previousRelease.time + 100 ) | |||
2989 | && !nextEvent2.xkey.send_event && nextEvent2.xkey.window == previousRelease.window | |||
2990 | && nextEvent2.xkey.state == previousRelease.state && nextEvent2.xkey.keycode == previousRelease.keycode ) | |||
2991 | { // And the matching keyrelease -> drop them both. | |||
2992 | discard1 = true; | |||
2993 | previousRelease = nextEvent2.xkey; | |||
2994 | ignore = false; // There either will be another autorepeating keypress that'll lead to discarding | |||
2995 | // the pEvent keyrelease, it this discarding makes that keyrelease the last one. | |||
2996 | } | |||
2997 | else | |||
2998 | { | |||
2999 | XPutBackEvent( dpy, &nextEvent2 ); | |||
3000 | break; | |||
3001 | } | |||
3002 | } | |||
3003 | } | |||
3004 | if( !discard1 ) | |||
3005 | { // Unrelated event, put back and stop compressing. | |||
3006 | XPutBackEvent( dpy, &nextEvent1 ); | |||
3007 | break; | |||
3008 | } | |||
3009 | } | |||
3010 | if( ignore ) // This autorepeating keyrelease is followed by another keypress. | |||
3011 | return false; | |||
3012 | } | |||
3013 | ||||
3014 | KeySym nKeySym; | |||
3015 | KeySym nUnmodifiedKeySym; | |||
3016 | int nLen = 2048; | |||
3017 | char *pPrintable = static_cast<char*>(alloca( nLen )__builtin_alloca (nLen)); | |||
3018 | ||||
3019 | // singlebyte code composed by input method, the new default | |||
3020 | if (mpInputContext != nullptr && mpInputContext->UseContext()) | |||
3021 | { | |||
3022 | // returns a keysym as well as the pPrintable (in system encoding) | |||
3023 | // printable may be empty. | |||
3024 | Statusint nStatus; | |||
3025 | nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen, | |||
3026 | &nUnmodifiedKeySym, | |||
3027 | &nStatus, mpInputContext->GetContext() ); | |||
3028 | if ( nStatus == XBufferOverflow-1 ) | |||
3029 | { | |||
3030 | // In case of overflow, XmbLookupString (called by GetKeySym) | |||
3031 | // returns required size | |||
3032 | // TODO : check if +1 is needed for 0 terminator | |||
3033 | nLen += 1; | |||
3034 | pPrintable = static_cast<char*>(alloca( nLen )__builtin_alloca (nLen)); | |||
3035 | nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen, | |||
3036 | &nUnmodifiedKeySym, | |||
3037 | &nStatus, mpInputContext->GetContext() ); | |||
3038 | } | |||
3039 | } | |||
3040 | else | |||
3041 | { | |||
3042 | // fallback, this should never ever be called | |||
3043 | Statusint nStatus = 0; | |||
3044 | nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen, &nUnmodifiedKeySym, &nStatus ); | |||
3045 | } | |||
3046 | ||||
3047 | SalKeyEvent aKeyEvt; | |||
3048 | sal_uInt16 nKeyCode; | |||
3049 | sal_uInt16 nModCode = 0; | |||
3050 | char aDummy; | |||
3051 | ||||
3052 | if( pEvent->state & ShiftMask(1<<0) ) | |||
3053 | nModCode |= KEY_SHIFT; | |||
3054 | if( pEvent->state & ControlMask(1<<2) ) | |||
3055 | nModCode |= KEY_MOD1; | |||
3056 | if( pEvent->state & Mod1Mask(1<<3) ) | |||
3057 | nModCode |= KEY_MOD2; | |||
3058 | ||||
3059 | if( nModCode != (KEY_SHIFT|KEY_MOD1) ) | |||
3060 | endUnicodeSequence(); | |||
3061 | ||||
3062 | if( nKeySym == XK_Shift_L0xffe1 || nKeySym == XK_Shift_R0xffe2 | |||
3063 | || nKeySym == XK_Control_L0xffe3 || nKeySym == XK_Control_R0xffe4 | |||
3064 | || nKeySym == XK_Alt_L0xffe9 || nKeySym == XK_Alt_R0xffea | |||
3065 | || nKeySym == XK_Meta_L0xffe7 || nKeySym == XK_Meta_R0xffe8 | |||
3066 | || nKeySym == XK_Super_L0xffeb || nKeySym == XK_Super_R0xffec ) | |||
3067 | { | |||
3068 | SalKeyModEvent aModEvt; | |||
3069 | aModEvt.mbDown = false; // auto-accelerator feature not supported here. | |||
3070 | aModEvt.mnModKeyCode = ModKeyFlags::NONE; | |||
3071 | if( pEvent->type == KeyPress2 && mnExtKeyMod == ModKeyFlags::NONE ) | |||
3072 | mbSendExtKeyModChange = true; | |||
3073 | else if( pEvent->type == KeyRelease3 && mbSendExtKeyModChange ) | |||
3074 | { | |||
3075 | aModEvt.mnModKeyCode = mnExtKeyMod; | |||
3076 | mnExtKeyMod = ModKeyFlags::NONE; | |||
3077 | } | |||
3078 | ||||
3079 | // pressing just the ctrl key leads to a keysym of XK_Control but | |||
3080 | // the event state does not contain ControlMask. In the release | |||
3081 | // event it's the other way round: it does contain the Control mask. | |||
3082 | // The modifier mode therefore has to be adapted manually. | |||
3083 | ModKeyFlags nExtModMask = ModKeyFlags::NONE; | |||
3084 | sal_uInt16 nModMask = 0; | |||
3085 | switch( nKeySym ) | |||
3086 | { | |||
3087 | case XK_Control_L0xffe3: | |||
3088 | nExtModMask = ModKeyFlags::LeftMod1; | |||
3089 | nModMask = KEY_MOD1; | |||
3090 | break; | |||
3091 | case XK_Control_R0xffe4: | |||
3092 | nExtModMask = ModKeyFlags::RightMod1; | |||
3093 | nModMask = KEY_MOD1; | |||
3094 | break; | |||
3095 | case XK_Alt_L0xffe9: | |||
3096 | nExtModMask = ModKeyFlags::LeftMod2; | |||
3097 | nModMask = KEY_MOD2; | |||
3098 | break; | |||
3099 | case XK_Alt_R0xffea: | |||
3100 | nExtModMask = ModKeyFlags::RightMod2; | |||
3101 | nModMask = KEY_MOD2; | |||
3102 | break; | |||
3103 | case XK_Shift_L0xffe1: | |||
3104 | nExtModMask = ModKeyFlags::LeftShift; | |||
3105 | nModMask = KEY_SHIFT; | |||
3106 | break; | |||
3107 | case XK_Shift_R0xffe2: | |||
3108 | nExtModMask = ModKeyFlags::RightShift; | |||
3109 | nModMask = KEY_SHIFT; | |||
3110 | break; | |||
3111 | // Map Meta/Super keys to MOD3 modifier on all Unix systems | |||
3112 | // except macOS | |||
3113 | case XK_Meta_L0xffe7: | |||
3114 | case XK_Super_L0xffeb: | |||
3115 | nExtModMask = ModKeyFlags::LeftMod3; | |||
3116 | nModMask = KEY_MOD3; | |||
3117 | break; | |||
3118 | case XK_Meta_R0xffe8: | |||
3119 | case XK_Super_R0xffec: | |||
3120 | nExtModMask = ModKeyFlags::RightMod3; | |||
3121 | nModMask = KEY_MOD3; | |||
3122 | break; | |||
3123 | } | |||
3124 | if( pEvent->type == KeyRelease3 ) | |||
3125 | { | |||
3126 | nModCode &= ~nModMask; | |||
3127 | mnExtKeyMod &= ~nExtModMask; | |||
3128 | } | |||
3129 | else | |||
3130 | { | |||
3131 | nModCode |= nModMask; | |||
3132 | mnExtKeyMod |= nExtModMask; | |||
3133 | } | |||
3134 | ||||
3135 | aModEvt.mnCode = nModCode; | |||
3136 | ||||
3137 | return CallCallback( SalEvent::KeyModChange, &aModEvt ); | |||
3138 | } | |||
3139 | ||||
3140 | mbSendExtKeyModChange = false; | |||
3141 | ||||
3142 | // try to figure out the vcl code for the keysym | |||
3143 | // #i52338# use the unmodified KeySym if there is none for the real KeySym | |||
3144 | // because the independent part has only keycodes for unshifted keys | |||
3145 | nKeyCode = pDisplay_->GetKeyCode( nKeySym, &aDummy ); | |||
3146 | if( nKeyCode == 0 ) | |||
3147 | nKeyCode = pDisplay_->GetKeyCode( nUnmodifiedKeySym, &aDummy ); | |||
3148 | ||||
3149 | // try to figure out a printable if XmbLookupString returns only a keysym | |||
3150 | // and NOT a printable. Do not store it in pPrintable[0] since it is expected to | |||
3151 | // be in system encoding, not unicode. | |||
3152 | // #i8988##, if KeySym and printable look equally promising then prefer KeySym | |||
3153 | // the printable is bound to the encoding so the KeySym might contain more | |||
3154 | // information (in et_EE locale: "Compose + Z + <" delivers "," in printable and | |||
3155 | // (the desired) Zcaron in KeySym | |||
3156 | sal_Unicode nKeyString = 0x0; | |||
3157 | if ( (nLen == 0) | |||
3158 | || ((nLen == 1) && (nKeySym > 0)) ) | |||
3159 | nKeyString = KeysymToUnicode (nKeySym); | |||
3160 | // if we have nothing we give up | |||
3161 | if( !nKeyCode && !nLen && !nKeyString) | |||
3162 | return false; | |||
3163 | ||||
3164 | vcl::DeletionListener aDeleteWatch( this ); | |||
3165 | ||||
3166 | if( nModCode == (KEY_SHIFT | KEY_MOD1) && pEvent->type == KeyPress2 ) | |||
3167 | { | |||
3168 | sal_uInt16 nSeqKeyCode = pDisplay_->GetKeyCode( nUnmodifiedKeySym, &aDummy ); | |||
3169 | if( nSeqKeyCode == KEY_U ) | |||
3170 | { | |||
3171 | beginUnicodeSequence(); | |||
3172 | return true; | |||
3173 | } | |||
3174 | else if( nSeqKeyCode >= KEY_0 && nSeqKeyCode <= KEY_9 ) | |||
3175 | { | |||
3176 | if( appendUnicodeSequence( u'0' + sal_Unicode(nSeqKeyCode - KEY_0) ) ) | |||
3177 | return true; | |||
3178 | } | |||
3179 | else if( nSeqKeyCode >= KEY_A && nSeqKeyCode <= KEY_F ) | |||
3180 | { | |||
3181 | if( appendUnicodeSequence( u'a' + sal_Unicode(nSeqKeyCode - KEY_A) ) ) | |||
3182 | return true; | |||
3183 | } | |||
3184 | else | |||
3185 | endUnicodeSequence(); | |||
3186 | } | |||
3187 | ||||
3188 | if( aDeleteWatch.isDeleted() ) | |||
3189 | return false; | |||
3190 | ||||
3191 | rtl_TextEncoding nEncoding = osl_getThreadTextEncoding(); | |||
3192 | ||||
3193 | sal_Unicode *pBuffer; | |||
3194 | sal_Unicode *pString; | |||
3195 | sal_Size nBufferSize = nLen * 2; | |||
3196 | sal_Size nSize; | |||
3197 | pBuffer = static_cast<sal_Unicode*>(malloc( nBufferSize + 2 )); | |||
3198 | pBuffer[ 0 ] = 0; | |||
3199 | ||||
3200 | if (nKeyString != 0) | |||
3201 | { | |||
3202 | pString = &nKeyString; | |||
3203 | nSize = 1; | |||
3204 | } | |||
3205 | else if (nLen > 0 && nEncoding != RTL_TEXTENCODING_UNICODE(((rtl_TextEncoding) 0xFFFF))) | |||
3206 | { | |||
3207 | // create text converter | |||
3208 | rtl_TextToUnicodeConverter aConverter = | |||
3209 | rtl_createTextToUnicodeConverter( nEncoding ); | |||
3210 | rtl_TextToUnicodeContext aContext = | |||
3211 | rtl_createTextToUnicodeContext( aConverter ); | |||
3212 | ||||
3213 | sal_uInt32 nConversionInfo; | |||
3214 | sal_Size nConvertedChars; | |||
3215 | ||||
3216 | // convert to single byte text stream | |||
3217 | nSize = rtl_convertTextToUnicode( | |||
3218 | aConverter, aContext, | |||
3219 | reinterpret_cast<char*>(pPrintable), nLen, | |||
3220 | pBuffer, nBufferSize, | |||
3221 | RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE((sal_uInt32)0x0002) | | |||
3222 | RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE((sal_uInt32)0x0200), | |||
3223 | &nConversionInfo, &nConvertedChars ); | |||
3224 | ||||
3225 | // destroy converter | |||
3226 | rtl_destroyTextToUnicodeContext( aConverter, aContext ); | |||
3227 | rtl_destroyTextToUnicodeConverter( aConverter ); | |||
3228 | ||||
3229 | pString = pBuffer; | |||
3230 | } | |||
3231 | else if (nLen > 0 /* nEncoding == RTL_TEXTENCODING_UNICODE */) | |||
3232 | { | |||
3233 | pString = reinterpret_cast<sal_Unicode*>(pPrintable); | |||
3234 | nSize = nLen; | |||
3235 | } | |||
3236 | else | |||
3237 | { | |||
3238 | pString = pBuffer; | |||
3239 | nSize = 0; | |||
3240 | } | |||
3241 | ||||
3242 | if ( mpInputContext != nullptr | |||
3243 | && mpInputContext->UseContext() | |||
3244 | && KeyRelease3 != pEvent->type | |||
3245 | && ( (nSize > 1) | |||
3246 | || (nSize > 0 && mpInputContext->IsPreeditMode())) ) | |||
3247 | { | |||
3248 | mpInputContext->CommitKeyEvent(pString, nSize); | |||
3249 | } | |||
3250 | else | |||
3251 | // normal single character keyinput | |||
3252 | { | |||
3253 | aKeyEvt.mnCode = nKeyCode | nModCode; | |||
3254 | aKeyEvt.mnRepeat = 0; | |||
3255 | aKeyEvt.mnCharCode = pString[ 0 ]; | |||
3256 | ||||
3257 | if( KeyRelease3 == pEvent->type ) | |||
3258 | { | |||
3259 | CallCallback( SalEvent::KeyUp, &aKeyEvt ); | |||
3260 | } | |||
3261 | else | |||
3262 | { | |||
3263 | if ( ! CallCallback(SalEvent::KeyInput, &aKeyEvt) ) | |||
3264 | { | |||
3265 | // independent layer doesn't want to handle key-event, so check | |||
3266 | // whether the keycode may have an alternate meaning | |||
3267 | KeyAlternate aAlternate = GetAlternateKeyCode( nKeyCode ); | |||
3268 | if ( aAlternate.nKeyCode != 0 ) | |||
3269 | { | |||
3270 | aKeyEvt.mnCode = aAlternate.nKeyCode | nModCode; | |||
3271 | if( aAlternate.nCharCode ) | |||
3272 | aKeyEvt.mnCharCode = aAlternate.nCharCode; | |||
3273 | CallCallback(SalEvent::KeyInput, &aKeyEvt); | |||
3274 | } | |||
3275 | } | |||
3276 | } | |||
3277 | } | |||
3278 | ||||
3279 | // update the spot location for PreeditPosition IME style | |||
3280 | ||||
3281 | if (! aDeleteWatch.isDeleted()) | |||
3282 | { | |||
3283 | if (mpInputContext != nullptr && mpInputContext->UseContext()) | |||
3284 | mpInputContext->UpdateSpotLocation(); | |||
3285 | } | |||
3286 | ||||
3287 | free (pBuffer); | |||
3288 | return true; | |||
3289 | } | |||
3290 | ||||
3291 | bool X11SalFrame::HandleFocusEvent( XFocusChangeEvent const *pEvent ) | |||
3292 | { | |||
3293 | // ReflectionX in Windows mode changes focus while mouse is grabbed | |||
3294 | if( nVisibleFloats > 0 && GetDisplay()->getWMAdaptor()->getWindowManagerName() == "ReflectionX Windows" ) | |||
3295 | return true; | |||
3296 | ||||
3297 | /* ignore focusout resulting from keyboard grabs | |||
3298 | * we do not grab it and are not interested when | |||
3299 | * someone else does CDE e.g. does a XGrabKey on arrow keys | |||
3300 | * handle focus events with mode NotifyWhileGrabbed | |||
3301 | * because with CDE alt-tab focus changing we do not get | |||
3302 | * normal focus events | |||
3303 | * cast focus event to the input context, otherwise the | |||
3304 | * status window does not follow the application frame | |||
3305 | */ | |||
3306 | ||||
3307 | if ( mpInputContext != nullptr ) | |||
3308 | { | |||
3309 | if( FocusIn9 == pEvent->type ) | |||
3310 | mpInputContext->SetICFocus( this ); | |||
3311 | } | |||
3312 | ||||
3313 | if ( pEvent->mode == NotifyNormal0 || pEvent->mode == NotifyWhileGrabbed3 || | |||
3314 | ( ( nStyle_ & SalFrameStyleFlags::PLUG ) && pEvent->window == GetShellWindow() ) | |||
3315 | ) | |||
3316 | { | |||
3317 | if( hPresentationWindow != None0L && hPresentationWindow != GetShellWindow() ) | |||
3318 | return false; | |||
3319 | ||||
3320 | if( FocusIn9 == pEvent->type ) | |||
3321 | { | |||
3322 | GetSalData()->m_pInstance->updatePrinterUpdate(); | |||
3323 | mbInputFocus = True1; | |||
3324 | ImplSVData* pSVData = ImplGetSVData(); | |||
3325 | ||||
3326 | bool nRet = CallCallback( SalEvent::GetFocus, nullptr ); | |||
3327 | if ((mpParent != nullptr && nStyle_ == SalFrameStyleFlags::NONE) | |||
3328 | && pSVData->mpWinData->mpFirstFloat) | |||
3329 | { | |||
3330 | FloatWinPopupFlags nMode = pSVData->mpWinData->mpFirstFloat->GetPopupModeFlags(); | |||
3331 | pSVData->mpWinData->mpFirstFloat->SetPopupModeFlags( | |||
3332 | nMode & ~FloatWinPopupFlags::NoAppFocusClose); | |||
3333 | } | |||
3334 | return nRet; | |||
3335 | } | |||
3336 | else | |||
3337 | { | |||
3338 | mbInputFocus = False0; | |||
3339 | mbSendExtKeyModChange = false; | |||
3340 | mnExtKeyMod = ModKeyFlags::NONE; | |||
3341 | return CallCallback( SalEvent::LoseFocus, nullptr ); | |||
3342 | } | |||
3343 | } | |||
3344 | ||||
3345 | return false; | |||
3346 | } | |||
3347 | ||||
3348 | bool X11SalFrame::HandleExposeEvent( XEvent const *pEvent ) | |||
3349 | { | |||
3350 | XRectangle aRect = { 0, 0, 0, 0 }; | |||
3351 | sal_uInt16 nCount = 0; | |||
3352 | ||||
3353 | if( pEvent->type == Expose12 ) | |||
3354 | { | |||
3355 | aRect.x = pEvent->xexpose.x; | |||
3356 | aRect.y = pEvent->xexpose.y; | |||
3357 | aRect.width = pEvent->xexpose.width; | |||
3358 | aRect.height = pEvent->xexpose.height; | |||
3359 | nCount = pEvent->xexpose.count; | |||
3360 | } | |||
3361 | else if( pEvent->type == GraphicsExpose13 ) | |||
3362 | { | |||
3363 | aRect.x = pEvent->xgraphicsexpose.x; | |||
3364 | aRect.y = pEvent->xgraphicsexpose.y; | |||
3365 | aRect.width = pEvent->xgraphicsexpose.width; | |||
3366 | aRect.height = pEvent->xgraphicsexpose.height; | |||
3367 | nCount = pEvent->xgraphicsexpose.count; | |||
3368 | } | |||
3369 | ||||
3370 | if( IsOverrideRedirect() && mbFullScreen && | |||
3371 | aPresentationReparentList.empty() ) | |||
3372 | // we are in fullscreen mode -> override redirect | |||
3373 | // focus is possibly lost, so reget it | |||
3374 | XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToNone(int)0L, CurrentTime0L ); | |||
3375 | ||||
3376 | // width and height are extents, so they are of by one for rectangle | |||
3377 | maPaintRegion.Union( tools::Rectangle( Point(aRect.x, aRect.y), Size(aRect.width+1, aRect.height+1) ) ); | |||
3378 | ||||
3379 | if( nCount ) | |||
3380 | // wait for last expose rectangle, do not wait for resize timer | |||
3381 | // if a completed graphics expose sequence is available | |||
3382 | return true; | |||
3383 | ||||
3384 | SalPaintEvent aPEvt( maPaintRegion.Left(), maPaintRegion.Top(), maPaintRegion.GetWidth(), maPaintRegion.GetHeight() ); | |||
3385 | ||||
3386 | CallCallback( SalEvent::Paint, &aPEvt ); | |||
3387 | maPaintRegion = tools::Rectangle(); | |||
3388 | ||||
3389 | return true; | |||
3390 | } | |||
3391 | ||||
3392 | void X11SalFrame::RestackChildren( ::Window* pTopLevelWindows, int nTopLevelWindows ) | |||
3393 | { | |||
3394 | if( maChildren.empty() ) | |||
3395 | return; | |||
3396 | ||||
3397 | int nWindow = nTopLevelWindows; | |||
3398 | while( nWindow-- ) | |||
3399 | if( pTopLevelWindows[nWindow] == GetStackingWindow() ) | |||
3400 | break; | |||
3401 | if( nWindow < 0 ) | |||
3402 | return; | |||
3403 | ||||
3404 | for (auto const& child : maChildren) | |||
3405 | { | |||
3406 | if( child->bMapped_ ) | |||
3407 | { | |||
3408 | int nChild = nWindow; | |||
3409 | while( nChild-- ) | |||
3410 | { | |||
3411 | if( pTopLevelWindows[nChild] == child->GetStackingWindow() ) | |||
3412 | { | |||
3413 | // if a child is behind its parent, place it above the | |||
3414 | // parent (for insane WMs like Dtwm and olwm) | |||
3415 | XWindowChanges aCfg; | |||
3416 | aCfg.sibling = GetStackingWindow(); | |||
3417 | aCfg.stack_mode = Above0; | |||
3418 | XConfigureWindow( GetXDisplay(), child->GetStackingWindow(), CWSibling(1<<5)|CWStackMode(1<<6), &aCfg ); | |||
3419 | break; | |||
3420 | } | |||
3421 | } | |||
3422 | } | |||
3423 | } | |||
3424 | for (auto const& child : maChildren) | |||
3425 | { | |||
3426 | child->RestackChildren( pTopLevelWindows, nTopLevelWindows ); | |||
3427 | } | |||
3428 | } | |||
3429 | ||||
3430 | void X11SalFrame::RestackChildren() | |||
3431 | { | |||
3432 | if( maChildren.empty() ) | |||
3433 | return; | |||
3434 | ||||
3435 | ::Window aRoot, aParent, *pChildren = nullptr; | |||
3436 | unsigned int nChildren; | |||
3437 | if( XQueryTree( GetXDisplay(), | |||
3438 | GetDisplay()->GetRootWindow( m_nXScreen ), | |||
3439 | &aRoot, | |||
3440 | &aParent, | |||
3441 | &pChildren, | |||
3442 | &nChildren ) ) | |||
3443 | { | |||
3444 | RestackChildren( pChildren, nChildren ); | |||
3445 | XFree( pChildren ); | |||
3446 | } | |||
3447 | } | |||
3448 | ||||
3449 | static Boolint size_event_predicate( Display*, XEvent* event, XPointer arg ) | |||
3450 | { | |||
3451 | if( event->type != ConfigureNotify22 ) | |||
3452 | return False0; | |||
3453 | X11SalFrame* frame = reinterpret_cast< X11SalFrame* >( arg ); | |||
3454 | XConfigureEvent* pEvent = &event->xconfigure; | |||
3455 | if( pEvent->window != frame->GetShellWindow() | |||
3456 | && pEvent->window != frame->GetWindow() | |||
3457 | && pEvent->window != frame->GetForeignParent() | |||
3458 | && pEvent->window != frame->GetStackingWindow()) | |||
3459 | { // ignored at top of HandleSizeEvent() | |||
3460 | return False0; | |||
3461 | } | |||
3462 | if( pEvent->window == frame->GetStackingWindow()) | |||
3463 | return False0; // filtered later in HandleSizeEvent() | |||
3464 | // at this point we know that there is another similar event in the queue | |||
3465 | frame->setPendingSizeEvent(); | |||
3466 | return False0; // but do not process the new event out of order | |||
3467 | } | |||
3468 | ||||
3469 | void X11SalFrame::setPendingSizeEvent() | |||
3470 | { | |||
3471 | mPendingSizeEvent = true; | |||
3472 | } | |||
3473 | ||||
3474 | bool X11SalFrame::HandleSizeEvent( XConfigureEvent *pEvent ) | |||
3475 | { | |||
3476 | // NOTE: if you add more tests in this function, make sure to update size_event_predicate() | |||
3477 | // so that it finds exactly the same events | |||
3478 | ||||
3479 | if ( pEvent->window != GetShellWindow() | |||
3480 | && pEvent->window != GetWindow() | |||
3481 | && pEvent->window != GetForeignParent() | |||
3482 | && pEvent->window != GetStackingWindow() | |||
3483 | ) | |||
3484 | { | |||
3485 | // could be as well a sys-child window (aka SalObject) | |||
3486 | return true; | |||
3487 | } | |||
3488 | ||||
3489 | if( ( nStyle_ & SalFrameStyleFlags::PLUG ) && pEvent->window == GetShellWindow() ) | |||
3490 | { | |||
3491 | // just update the children's positions | |||
3492 | RestackChildren(); | |||
3493 | return true; | |||
3494 | } | |||
3495 | ||||
3496 | if( pEvent->window == GetForeignParent() ) | |||
3497 | XResizeWindow( GetXDisplay(), | |||
3498 | GetWindow(), | |||
3499 | pEvent->width, | |||
3500 | pEvent->height ); | |||
3501 | ||||
3502 | ::Window hDummy; | |||
3503 | XTranslateCoordinates( GetXDisplay(), | |||
3504 | GetWindow(), | |||
3505 | pDisplay_->GetRootWindow( pDisplay_->GetDefaultXScreen() ), | |||
3506 | 0, 0, | |||
3507 | &pEvent->x, &pEvent->y, | |||
3508 | &hDummy ); | |||
3509 | ||||
3510 | if( pEvent->window == GetStackingWindow() ) | |||
3511 | { | |||
3512 | if( maGeometry.nX != pEvent->x || maGeometry.nY != pEvent->y ) | |||
3513 | { | |||
3514 | maGeometry.nX = pEvent->x; | |||
3515 | maGeometry.nY = pEvent->y; | |||
3516 | CallCallback( SalEvent::Move, nullptr ); | |||
3517 | } | |||
3518 | return true; | |||
3519 | } | |||
3520 | ||||
3521 | // check size hints in first time SalFrame::Show | |||
3522 | if( SHOWSTATE_UNKNOWN-1 == nShowState_ && bMapped_ ) | |||
3523 | nShowState_ = SHOWSTATE_NORMAL1; | |||
3524 | ||||
3525 | // Avoid a race condition where resizing this window to one size and shortly after that | |||
3526 | // to another size generates first size event with the old size and only after that | |||
3527 | // with the new size, temporarily making us think the old size is valid (bnc#674806). | |||
3528 | // So if there is another size event for this window pending, ignore this one. | |||
3529 | mPendingSizeEvent = false; | |||
3530 | XEvent dummy; | |||
3531 | XCheckIfEvent( GetXDisplay(), &dummy, size_event_predicate, reinterpret_cast< XPointer >( this )); | |||
3532 | if( mPendingSizeEvent ) | |||
3533 | return true; | |||
3534 | ||||
3535 | nWidth_ = pEvent->width; | |||
3536 | nHeight_ = pEvent->height; | |||
3537 | ||||
3538 | bool bMoved = ( pEvent->x != maGeometry.nX || pEvent->y != maGeometry.nY ); | |||
3539 | bool bSized = ( pEvent->width != static_cast<int>(maGeometry.nWidth) || pEvent->height != static_cast<int>(maGeometry.nHeight) ); | |||
3540 | ||||
3541 | maGeometry.nX = pEvent->x; | |||
3542 | maGeometry.nY = pEvent->y; | |||
3543 | maGeometry.nWidth = pEvent->width; | |||
3544 | maGeometry.nHeight = pEvent->height; | |||
3545 | updateScreenNumber(); | |||
3546 | ||||
3547 | // update children's position | |||
3548 | RestackChildren(); | |||
3549 | ||||
3550 | if( bSized && ! bMoved ) | |||
3551 | CallCallback( SalEvent::Resize, nullptr ); | |||
3552 | else if( bMoved && ! bSized ) | |||
3553 | CallCallback( SalEvent::Move, nullptr ); | |||
3554 | else if( bMoved && bSized ) | |||
3555 | CallCallback( SalEvent::MoveResize, nullptr ); | |||
3556 | ||||
3557 | return true; | |||
3558 | } | |||
3559 | ||||
3560 | IMPL_LINK_NOARG(X11SalFrame, HandleAlwaysOnTopRaise, Timer *, void)void X11SalFrame::LinkStubHandleAlwaysOnTopRaise(void * instance , Timer * data) { return static_cast<X11SalFrame *>(instance )->HandleAlwaysOnTopRaise(data); } void X11SalFrame::HandleAlwaysOnTopRaise (__attribute__ ((unused)) Timer *) | |||
3561 | { | |||
3562 | if( bMapped_ ) | |||
3563 | ToTop( SalFrameToTop::NONE ); | |||
3564 | } | |||
3565 | ||||
3566 | bool X11SalFrame::HandleReparentEvent( XReparentEvent *pEvent ) | |||
3567 | { | |||
3568 | Display *pDisplay = pEvent->display; | |||
3569 | ::Window hWM_Parent; | |||
3570 | ::Window hRoot, *Children, hDummy; | |||
3571 | unsigned int nChildren; | |||
3572 | ||||
3573 | static const char* pDisableStackingCheck = getenv( "SAL_DISABLE_STACKING_CHECK" ); | |||
3574 | ||||
3575 | GetGenericUnixSalData()->ErrorTrapPush(); | |||
3576 | ||||
3577 | /* | |||
3578 | * don't rely on the new parent from the event. | |||
3579 | * the event may be "out of date", that is the window manager | |||
3580 | * window may not exist anymore. This can happen if someone | |||
3581 | * shows a frame and hides it again quickly (not that it would | |||
3582 | * be very sensible) | |||
3583 | */ | |||
3584 | hWM_Parent = GetShellWindow(); | |||
3585 | do | |||
3586 | { | |||
3587 | Children = nullptr; | |||
3588 | XQueryTree( pDisplay, | |||
3589 | hWM_Parent, | |||
3590 | &hRoot, | |||
3591 | &hDummy, | |||
3592 | &Children, | |||
3593 | &nChildren ); | |||
3594 | ||||
3595 | bool bError = GetGenericUnixSalData()->ErrorTrapPop( false ); | |||
3596 | GetGenericUnixSalData()->ErrorTrapPush(); | |||
3597 | ||||
3598 | if( bError ) | |||
3599 | { | |||
3600 | hWM_Parent = GetShellWindow(); | |||
3601 | break; | |||
3602 | } | |||
3603 | /* this sometimes happens if a Show(true) is | |||
3604 | * immediately followed by Show(false) (which is braindead anyway) | |||
3605 | */ | |||
3606 | if( hDummy == hWM_Parent ) | |||
3607 | hDummy = hRoot; | |||
3608 | if( hDummy != hRoot ) | |||
3609 | hWM_Parent = hDummy; | |||
3610 | if( Children ) | |||
3611 | XFree( Children ); | |||
3612 | } while( hDummy != hRoot ); | |||
3613 | ||||
3614 | if( GetStackingWindow() == None0L | |||
3615 | && hWM_Parent != hPresentationWindow | |||
3616 | && hWM_Parent != GetShellWindow() | |||
3617 | && ( ! pDisableStackingCheck || ! *pDisableStackingCheck ) | |||
3618 | ) | |||
3619 | { | |||
3620 | mhStackingWindow = hWM_Parent; | |||
3621 | XSelectInput( pDisplay, GetStackingWindow(), StructureNotifyMask(1L<<17) ); | |||
3622 | } | |||
3623 | ||||
3624 | if( hWM_Parent == pDisplay_->GetRootWindow( pDisplay_->GetDefaultXScreen() ) | |||
3625 | || hWM_Parent == GetForeignParent() | |||
3626 | || pEvent->parent == pDisplay_->GetRootWindow( pDisplay_->GetDefaultXScreen() ) | |||
3627 | || ( nStyle_ & SalFrameStyleFlags::FLOAT ) ) | |||
3628 | { | |||
3629 | // Reparenting before Destroy | |||
3630 | aPresentationReparentList.remove( GetStackingWindow() ); | |||
3631 | mhStackingWindow = None0L; | |||
3632 | GetGenericUnixSalData()->ErrorTrapPop(); | |||
3633 | return false; | |||
3634 | } | |||
3635 | ||||
3636 | /* | |||
3637 | * evil hack to show decorated windows on top | |||
3638 | * of override redirect presentation windows: | |||
3639 | * reparent the window manager window to the presentation window | |||
3640 | * does not work with non-reparenting WMs | |||
3641 | * in future this should not be necessary anymore with | |||
3642 | * _NET_WM_STATE_FULLSCREEN available | |||
3643 | */ | |||
3644 | if( hPresentationWindow != None0L | |||
3645 | && hPresentationWindow != GetWindow() | |||
3646 | && GetStackingWindow() != None0L | |||
3647 | && GetStackingWindow() != GetDisplay()->GetRootWindow( m_nXScreen ) | |||
3648 | ) | |||
3649 | { | |||
3650 | int x = 0, y = 0; | |||
3651 | ::Window aChild; | |||
3652 | XTranslateCoordinates( GetXDisplay(), | |||
3653 | GetStackingWindow(), | |||
3654 | GetDisplay()->GetRootWindow( m_nXScreen ), | |||
3655 | 0, 0, | |||
3656 | &x, &y, | |||
3657 | &aChild | |||
3658 | ); | |||
3659 | XReparentWindow( GetXDisplay(), | |||
3660 | GetStackingWindow(), | |||
3661 | hPresentationWindow, | |||
3662 | x, y | |||
3663 | ); | |||
3664 | aPresentationReparentList.push_back( GetStackingWindow() ); | |||
3665 | } | |||
3666 | ||||
3667 | int nLeft = 0, nTop = 0; | |||
3668 | XTranslateCoordinates( GetXDisplay(), | |||
3669 | GetShellWindow(), | |||
3670 | hWM_Parent, | |||
3671 | 0, 0, | |||
3672 | &nLeft, | |||
3673 | &nTop, | |||
3674 | &hDummy ); | |||
3675 | maGeometry.nLeftDecoration = nLeft > 0 ? nLeft-1 : 0; | |||
3676 | maGeometry.nTopDecoration = nTop > 0 ? nTop-1 : 0; | |||
3677 | ||||
3678 | /* | |||
3679 | * decorations are not symmetric, | |||
3680 | * so need real geometries here | |||
3681 | * (this will fail with virtual roots ?) | |||
3682 | */ | |||
3683 | ||||
3684 | // reset error occurred | |||
3685 | GetGenericUnixSalData()->ErrorTrapPop(); | |||
3686 | GetGenericUnixSalData()->ErrorTrapPush(); | |||
3687 | ||||
3688 | int xp, yp, x, y; | |||
3689 | unsigned int wp, w, hp, h, bw, d; | |||
3690 | XGetGeometry( GetXDisplay(), | |||
3691 | GetShellWindow(), | |||
3692 | &hRoot, | |||
3693 | &x, &y, &w, &h, &bw, &d ); | |||
3694 | XGetGeometry( GetXDisplay(), | |||
3695 | hWM_Parent, | |||
3696 | &hRoot, | |||
3697 | &xp, &yp, &wp, &hp, &bw, &d ); | |||
3698 | bool bResized = false; | |||
3699 | bool bError = GetGenericUnixSalData()->ErrorTrapPop( false ); | |||
3700 | GetGenericUnixSalData()->ErrorTrapPush(); | |||
3701 | ||||
3702 | if( ! bError ) | |||
3703 | { | |||
3704 | maGeometry.nRightDecoration = wp - w - maGeometry.nLeftDecoration; | |||
3705 | maGeometry.nBottomDecoration = hp - h - maGeometry.nTopDecoration; | |||
3706 | /* | |||
3707 | * note: this works because hWM_Parent is direct child of root, | |||
3708 | * not necessarily parent of GetShellWindow() | |||
3709 | */ | |||
3710 | maGeometry.nX = xp + nLeft; | |||
3711 | maGeometry.nY = yp + nTop; | |||
3712 | bResized = w != maGeometry.nWidth || h != maGeometry.nHeight; | |||
3713 | maGeometry.nWidth = w; | |||
3714 | maGeometry.nHeight = h; | |||
3715 | } | |||
3716 | ||||
3717 | // limit width and height if we are too large: #47757 | |||
3718 | // olwm and fvwm need this, it doesn't harm the rest | |||
3719 | ||||
3720 | // #i81311# do this only for sizable frames | |||
3721 | if( nStyle_ & SalFrameStyleFlags::SIZEABLE ) | |||
3722 | { | |||
3723 | Size aScreenSize = GetDisplay()->GetScreenSize( m_nXScreen ); | |||
3724 | int nScreenWidth = aScreenSize.Width(); | |||
3725 | int nScreenHeight = aScreenSize.Height(); | |||
3726 | int nFrameWidth = maGeometry.nWidth + maGeometry.nLeftDecoration + maGeometry.nRightDecoration; | |||
3727 | int nFrameHeight = maGeometry.nHeight + maGeometry.nTopDecoration + maGeometry.nBottomDecoration; | |||
3728 | ||||
3729 | if ((nFrameWidth > nScreenWidth) || (nFrameHeight > nScreenHeight)) | |||
3730 | { | |||
3731 | Size aSize(maGeometry.nWidth, maGeometry.nHeight); | |||
3732 | ||||
3733 | if (nFrameWidth > nScreenWidth) | |||
3734 | aSize.setWidth( nScreenWidth - maGeometry.nRightDecoration - maGeometry.nLeftDecoration ); | |||
3735 | if (nFrameHeight > nScreenHeight) | |||
3736 | aSize.setHeight( nScreenHeight - maGeometry.nBottomDecoration - maGeometry.nTopDecoration ); | |||
3737 | ||||
3738 | SetSize( aSize ); | |||
3739 | bResized = false; | |||
3740 | } | |||
3741 | } | |||
3742 | if( bResized ) | |||
3743 | CallCallback( SalEvent::Resize, nullptr ); | |||
3744 | ||||
3745 | GetGenericUnixSalData()->ErrorTrapPop(); | |||
3746 | ||||
3747 | return true; | |||
3748 | } | |||
3749 | ||||
3750 | bool X11SalFrame::HandleStateEvent( XPropertyEvent const *pEvent ) | |||
3751 | { | |||
3752 | Atom actual_type; | |||
3753 | int actual_format; | |||
3754 | unsigned long nitems, bytes_after; | |||
3755 | unsigned char *prop = nullptr; | |||
3756 | ||||
3757 | if( 0 != XGetWindowProperty( GetXDisplay(), | |||
3758 | GetShellWindow(), | |||
3759 | pEvent->atom, // property | |||
3760 | 0, // long_offset (32bit) | |||
3761 | 2, // long_length (32bit) | |||
3762 | False0, // delete | |||
3763 | pEvent->atom, // req_type | |||
3764 | &actual_type, | |||
3765 | &actual_format, | |||
3766 | &nitems, | |||
3767 | &bytes_after, | |||
3768 | &prop ) | |||
3769 | || ! prop | |||
3770 | ) | |||
3771 | return false; | |||
3772 | ||||
3773 | DBG_ASSERT( actual_type == pEvent->atomdo { if (true && (!(actual_type == pEvent->atom && 32 == actual_format && 2 == nitems && 0 == bytes_after ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3776" ": "), "%s", "HandleStateEvent"); } } while (false ) | |||
3774 | && 32 == actual_formatdo { if (true && (!(actual_type == pEvent->atom && 32 == actual_format && 2 == nitems && 0 == bytes_after ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3776" ": "), "%s", "HandleStateEvent"); } } while (false ) | |||
3775 | && 2 == nitemsdo { if (true && (!(actual_type == pEvent->atom && 32 == actual_format && 2 == nitems && 0 == bytes_after ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3776" ": "), "%s", "HandleStateEvent"); } } while (false ) | |||
3776 | && 0 == bytes_after, "HandleStateEvent" )do { if (true && (!(actual_type == pEvent->atom && 32 == actual_format && 2 == nitems && 0 == bytes_after ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3776" ": "), "%s", "HandleStateEvent"); } } while (false ); | |||
3777 | ||||
3778 | if( *reinterpret_cast<unsigned long*>(prop) == NormalState1 ) | |||
3779 | nShowState_ = SHOWSTATE_NORMAL1; | |||
3780 | else if( *reinterpret_cast<unsigned long*>(prop) == IconicState3 ) | |||
3781 | nShowState_ = SHOWSTATE_MINIMIZED0; | |||
3782 | ||||
3783 | XFree( prop ); | |||
3784 | return true; | |||
3785 | } | |||
3786 | ||||
3787 | bool X11SalFrame::HandleClientMessage( XClientMessageEvent *pEvent ) | |||
3788 | { | |||
3789 | const WMAdaptor& rWMAdaptor( *pDisplay_->getWMAdaptor() ); | |||
3790 | ||||
3791 | #if !defined(__synchronous_extinput__) | |||
3792 | if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::SAL_EXTTEXTEVENT ) ) | |||
3793 | { | |||
3794 | HandleExtTextEvent (pEvent); | |||
3795 | return true; | |||
3796 | } | |||
3797 | #endif | |||
3798 | else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::SAL_QUITEVENT ) ) | |||
3799 | { | |||
3800 | SAL_WARN( "vcl", "X11SalFrame::Dispatch Quit" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::Dispatch Quit") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3800" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::Dispatch Quit"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::Dispatch Quit"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3800" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "X11SalFrame::Dispatch Quit") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3800" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "X11SalFrame::Dispatch Quit"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "X11SalFrame::Dispatch Quit"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3800" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
3801 | Close(); // ??? | |||
3802 | return true; | |||
3803 | } | |||
3804 | else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::WM_PROTOCOLS ) ) | |||
3805 | { | |||
3806 | if( static_cast<Atom>(pEvent->data.l[0]) == rWMAdaptor.getAtom( WMAdaptor::NET_WM_PING ) ) | |||
3807 | rWMAdaptor.answerPing( this, pEvent ); | |||
3808 | else if( ! ( nStyle_ & SalFrameStyleFlags::PLUG ) | |||
3809 | && ! (( nStyle_ & SalFrameStyleFlags::FLOAT ) && (nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION)) | |||
3810 | ) | |||
3811 | { | |||
3812 | if( static_cast<Atom>(pEvent->data.l[0]) == rWMAdaptor.getAtom( WMAdaptor::WM_DELETE_WINDOW ) ) | |||
3813 | { | |||
3814 | Close(); | |||
3815 | return true; | |||
3816 | } | |||
3817 | else if( static_cast<Atom>(pEvent->data.l[0]) == rWMAdaptor.getAtom( WMAdaptor::WM_TAKE_FOCUS ) ) | |||
3818 | { | |||
3819 | // do nothing, we set the input focus in ToTop() if necessary | |||
3820 | #if OSL_DEBUG_LEVEL1 > 1 | |||
3821 | SAL_INFO("vcl.window", "got WM_TAKE_FOCUS on "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION ) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
3822 | << ((nStyle_ &do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION ) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
3823 | SalFrameStyleFlags::OWNERDRAWDECORATION) ?do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION ) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
3824 | "ownerdraw" :do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION ) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
3825 | "NON OWNERDRAW" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION ) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
3826 | << " window.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION ) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.window" ), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "got WM_TAKE_FOCUS on " << ((nStyle_ & SalFrameStyleFlags ::OWNERDRAWDECORATION) ? "ownerdraw" : "NON OWNERDRAW" ) << " window."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/unx/generic/window/salframe.cxx" ":" "3826" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
3827 | #endif | |||
3828 | } | |||
3829 | } | |||
3830 | } | |||
3831 | else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::XEMBED ) && | |||
3832 | pEvent->window == GetWindow() ) | |||
3833 | { | |||
3834 | if( pEvent->data.l[1] == 1 || // XEMBED_WINDOW_ACTIVATE | |||
3835 | pEvent->data.l[1] == 2 ) // XEMBED_WINDOW_DEACTIVATE | |||
3836 | { | |||
3837 | XFocusChangeEvent aEvent; | |||
3838 | aEvent.type = (pEvent->data.l[1] == 1 ? FocusIn9 : FocusOut10); | |||
3839 | aEvent.serial = pEvent->serial; | |||
3840 | aEvent.send_event = True1; | |||
3841 | aEvent.display = pEvent->display; | |||
3842 | aEvent.window = pEvent->window; | |||
3843 | aEvent.mode = NotifyNormal0; | |||
3844 | aEvent.detail = NotifyDetailNone7; | |||
3845 | HandleFocusEvent( &aEvent ); | |||
3846 | } | |||
3847 | } | |||
3848 | return false; | |||
3849 | } | |||
3850 | ||||
3851 | bool X11SalFrame::Dispatch( XEvent *pEvent ) | |||
3852 | { | |||
3853 | bool nRet = false; | |||
3854 | ||||
3855 | if( -1 == nCaptured_ ) | |||
3856 | { | |||
3857 | CaptureMouse( true ); | |||
3858 | #ifdef DBG_UTIL | |||
3859 | if( -1 != nCaptured_ ) | |||
3860 | pDisplay_->DbgPrintDisplayEvent("Captured", pEvent); | |||
3861 | #endif | |||
3862 | } | |||
3863 | ||||
3864 | if( pEvent->xany.window == GetShellWindow() || pEvent->xany.window == GetWindow() ) | |||
3865 | { | |||
3866 | switch( pEvent->type ) | |||
3867 | { | |||
3868 | case KeyPress2: | |||
3869 | nRet = HandleKeyEvent( &pEvent->xkey ); | |||
3870 | break; | |||
3871 | ||||
3872 | case KeyRelease3: | |||
3873 | nRet = HandleKeyEvent( &pEvent->xkey ); | |||
3874 | break; | |||
3875 | ||||
3876 | case ButtonPress4: | |||
3877 | // if we lose the focus in presentation mode | |||
3878 | // there are good chances that we never get it back | |||
3879 | // since the WM ignores us | |||
3880 | if( IsOverrideRedirect() ) | |||
3881 | { | |||
3882 | XSetInputFocus( GetXDisplay(), GetShellWindow(), | |||
3883 | RevertToNone(int)0L, CurrentTime0L ); | |||
3884 | } | |||
3885 | [[fallthrough]]; | |||
3886 | case ButtonRelease5: | |||
3887 | case MotionNotify6: | |||
3888 | case EnterNotify7: | |||
3889 | case LeaveNotify8: | |||
3890 | nRet = HandleMouseEvent( pEvent ); | |||
3891 | break; | |||
3892 | ||||
3893 | case FocusIn9: | |||
3894 | case FocusOut10: | |||
3895 | nRet = HandleFocusEvent( &pEvent->xfocus ); | |||
3896 | break; | |||
3897 | ||||
3898 | case Expose12: | |||
3899 | case GraphicsExpose13: | |||
3900 | nRet = HandleExposeEvent( pEvent ); | |||
3901 | break; | |||
3902 | ||||
3903 | case MapNotify19: | |||
3904 | if( pEvent->xmap.window == GetShellWindow() ) | |||
3905 | { | |||
3906 | if( nShowState_ == SHOWSTATE_HIDDEN2 ) | |||
3907 | { | |||
3908 | /* | |||
3909 | * workaround for (at least) KWin 2.2.2 | |||
3910 | * which will map windows that were once transient | |||
3911 | * even if they are withdrawn when the respective | |||
3912 | * document is mapped. | |||
3913 | */ | |||
3914 | if( ! (nStyle_ & SalFrameStyleFlags::PLUG) ) | |||
3915 | XUnmapWindow( GetXDisplay(), GetShellWindow() ); | |||
3916 | break; | |||
3917 | } | |||
3918 | bMapped_ = true; | |||
3919 | bViewable_ = true; | |||
3920 | nRet = true; | |||
3921 | if ( mpInputContext != nullptr ) | |||
3922 | mpInputContext->Map( this ); | |||
3923 | CallCallback( SalEvent::Resize, nullptr ); | |||
3924 | ||||
3925 | bool bSetFocus = m_bSetFocusOnMap; | |||
3926 | ||||
3927 | /* | |||
3928 | * sometimes a message box/dialogue is brought up when a frame is not mapped | |||
3929 | * the corresponding TRANSIENT_FOR hint is then set to the root window | |||
3930 | * so that the dialogue shows in all cases. Correct it here if the | |||
3931 | * frame is shown afterwards. | |||
3932 | */ | |||
3933 | if( ! IsChildWindow() | |||
3934 | && ! IsOverrideRedirect() | |||
3935 | && ! IsFloatGrabWindow() | |||
3936 | ) | |||
3937 | { | |||
3938 | for (auto const& child : maChildren) | |||
3939 | { | |||
3940 | if( child->mbTransientForRoot ) | |||
3941 | pDisplay_->getWMAdaptor()->changeReferenceFrame( child, this ); | |||
3942 | } | |||
3943 | } | |||
3944 | ||||
3945 | if( hPresentationWindow != None0L && GetShellWindow() == hPresentationWindow ) | |||
3946 | XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToParent2, CurrentTime0L ); | |||
3947 | ||||
3948 | if( bSetFocus ) | |||
3949 | { | |||
3950 | XSetInputFocus( GetXDisplay(), | |||
3951 | GetShellWindow(), | |||
3952 | RevertToParent2, | |||
3953 | CurrentTime0L ); | |||
3954 | } | |||
3955 | ||||
3956 | RestackChildren(); | |||
3957 | m_bSetFocusOnMap = false; | |||
3958 | } | |||
3959 | break; | |||
3960 | ||||
3961 | case UnmapNotify18: | |||
3962 | if( pEvent->xunmap.window == GetShellWindow() ) | |||
3963 | { | |||
3964 | bMapped_ = false; | |||
3965 | bViewable_ = false; | |||
3966 | nRet = true; | |||
3967 | if ( mpInputContext != nullptr ) | |||
3968 | mpInputContext->Unmap(); | |||
3969 | CallCallback( SalEvent::Resize, nullptr ); | |||
3970 | } | |||
3971 | break; | |||
3972 | ||||
3973 | case ConfigureNotify22: | |||
3974 | if( pEvent->xconfigure.window == GetShellWindow() | |||
3975 | || pEvent->xconfigure.window == GetWindow() ) | |||
3976 | nRet = HandleSizeEvent( &pEvent->xconfigure ); | |||
3977 | break; | |||
3978 | ||||
3979 | case VisibilityNotify15: | |||
3980 | nVisibility_ = pEvent->xvisibility.state; | |||
3981 | nRet = true; | |||
3982 | if( bAlwaysOnTop_ | |||
3983 | && bMapped_ | |||
3984 | && ! GetDisplay()->getWMAdaptor()->isAlwaysOnTopOK() | |||
3985 | && nVisibility_ != VisibilityUnobscured0 ) | |||
3986 | maAlwaysOnTopRaiseTimer.Start(); | |||
3987 | break; | |||
3988 | ||||
3989 | case ReparentNotify21: | |||
3990 | nRet = HandleReparentEvent( &pEvent->xreparent ); | |||
3991 | break; | |||
3992 | ||||
3993 | case MappingNotify34: | |||
3994 | break; | |||
3995 | ||||
3996 | case ColormapNotify32: | |||
3997 | nRet = false; | |||
3998 | break; | |||
3999 | ||||
4000 | case PropertyNotify28: | |||
4001 | { | |||
4002 | if( pEvent->xproperty.atom == pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_STATE ) ) | |||
4003 | nRet = HandleStateEvent( &pEvent->xproperty ); | |||
4004 | else | |||
4005 | nRet = pDisplay_->getWMAdaptor()->handlePropertyNotify( this, &pEvent->xproperty ); | |||
4006 | break; | |||
4007 | } | |||
4008 | ||||
4009 | case ClientMessage33: | |||
4010 | nRet = HandleClientMessage( &pEvent->xclient ); | |||
4011 | break; | |||
4012 | } | |||
4013 | } | |||
4014 | else | |||
4015 | { | |||
4016 | switch( pEvent->type ) | |||
4017 | { | |||
4018 | case FocusIn9: | |||
4019 | case FocusOut10: | |||
4020 | if( ( nStyle_ & SalFrameStyleFlags::PLUG ) | |||
4021 | && ( pEvent->xfocus.window == GetShellWindow() | |||
4022 | || pEvent->xfocus.window == GetForeignParent() ) | |||
4023 | ) | |||
4024 | { | |||
4025 | nRet = HandleFocusEvent( &pEvent->xfocus ); | |||
4026 | } | |||
4027 | break; | |||
4028 | ||||
4029 | case ConfigureNotify22: | |||
4030 | if( pEvent->xconfigure.window == GetForeignParent() || | |||
4031 | pEvent->xconfigure.window == GetShellWindow() ) | |||
4032 | nRet = HandleSizeEvent( &pEvent->xconfigure ); | |||
4033 | ||||
4034 | if( pEvent->xconfigure.window == GetStackingWindow() ) | |||
4035 | nRet = HandleSizeEvent( &pEvent->xconfigure ); | |||
4036 | ||||
4037 | RestackChildren(); | |||
4038 | break; | |||
4039 | } | |||
4040 | } | |||
4041 | ||||
4042 | return nRet; | |||
4043 | } | |||
4044 | ||||
4045 | void X11SalFrame::ResetClipRegion() | |||
4046 | { | |||
4047 | m_vClipRectangles.clear(); | |||
4048 | ||||
4049 | const int dest_kind = ShapeBounding0; | |||
4050 | const int op = ShapeSet0; | |||
4051 | const int ordering = YSorted1; | |||
4052 | ||||
4053 | XWindowAttributes win_attrib; | |||
4054 | XRectangle win_size; | |||
4055 | ||||
4056 | ::Window aShapeWindow = mhShellWindow; | |||
4057 | ||||
4058 | XGetWindowAttributes ( GetDisplay()->GetDisplay(), | |||
4059 | aShapeWindow, | |||
4060 | &win_attrib ); | |||
4061 | ||||
4062 | win_size.x = 0; | |||
4063 | win_size.y = 0; | |||
4064 | win_size.width = win_attrib.width; | |||
4065 | win_size.height = win_attrib.height; | |||
4066 | ||||
4067 | XShapeCombineRectangles ( GetDisplay()->GetDisplay(), | |||
4068 | aShapeWindow, | |||
4069 | dest_kind, | |||
4070 | 0, 0, // x_off, y_off | |||
4071 | &win_size, // list of rectangles | |||
4072 | 1, // number of rectangles | |||
4073 | op, ordering ); | |||
4074 | } | |||
4075 | ||||
4076 | void X11SalFrame::BeginSetClipRegion( sal_uInt32 /*nRects*/ ) | |||
4077 | { | |||
4078 | m_vClipRectangles.clear(); | |||
4079 | } | |||
4080 | ||||
4081 | void X11SalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) | |||
4082 | { | |||
4083 | m_vClipRectangles.emplace_back( XRectangle { static_cast<short>(nX), static_cast<short>(nY), | |||
4084 | static_cast<unsigned short>(nWidth), static_cast<unsigned short>(nHeight) } ); | |||
4085 | } | |||
4086 | ||||
4087 | void X11SalFrame::EndSetClipRegion() | |||
4088 | { | |||
4089 | const int dest_kind = ShapeBounding0; | |||
4090 | const int ordering = YSorted1; | |||
4091 | const int op = ShapeSet0; | |||
4092 | ||||
4093 | ::Window aShapeWindow = mhShellWindow; | |||
4094 | XShapeCombineRectangles ( GetDisplay()->GetDisplay(), | |||
4095 | aShapeWindow, | |||
4096 | dest_kind, | |||
4097 | 0, 0, // x_off, y_off | |||
4098 | m_vClipRectangles.data(), | |||
4099 | m_vClipRectangles.size(), | |||
4100 | op, ordering ); | |||
4101 | ||||
4102 | } | |||
4103 | ||||
4104 | sal_uIntPtr X11SalFrame::GetNativeWindowHandle() | |||
4105 | { | |||
4106 | return mhWindow; | |||
4107 | } | |||
4108 | ||||
4109 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |