Line data Source code
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 <stdio.h>
22 : #include <stdlib.h>
23 :
24 : #include "sal/alloca.h"
25 : #include "rtl/locale.h"
26 :
27 : #include "osl/thread.h"
28 : #include "osl/process.h"
29 : #include <sal/macros.h>
30 : #include "vcl/configsettings.hxx"
31 :
32 : #include "unx/wmadaptor.hxx"
33 : #include "unx/saldisp.hxx"
34 : #include "unx/saldata.hxx"
35 : #include "unx/salframe.h"
36 :
37 : #include "salgdi.hxx"
38 :
39 : #include <prex.h>
40 : #include <X11/X.h>
41 : #include <X11/Xatom.h>
42 : #include <X11/Xresource.h>
43 : #include <postx.h>
44 :
45 : namespace vcl_sal {
46 :
47 : class NetWMAdaptor : public WMAdaptor
48 : {
49 : void setNetWMState( X11SalFrame* pFrame ) const;
50 : void initAtoms();
51 : virtual bool isValid() const SAL_OVERRIDE;
52 : public:
53 : NetWMAdaptor( SalDisplay* );
54 : virtual ~NetWMAdaptor();
55 :
56 : virtual void setWMName( X11SalFrame* pFrame, const OUString& rWMName ) const SAL_OVERRIDE;
57 : virtual void maximizeFrame( X11SalFrame* pFrame, bool bHorizontal = true, bool bVertical = true ) const SAL_OVERRIDE;
58 : virtual void shade( X11SalFrame* pFrame, bool bToShaded ) const SAL_OVERRIDE;
59 : virtual void setFrameTypeAndDecoration( X11SalFrame* pFrame, WMWindowType eType, int nDecorationFlags, X11SalFrame* pTransientFrame = NULL ) const SAL_OVERRIDE;
60 : virtual void enableAlwaysOnTop( X11SalFrame* pFrame, bool bEnable ) const SAL_OVERRIDE;
61 : virtual int handlePropertyNotify( X11SalFrame* pFrame, XPropertyEvent* pEvent ) const SAL_OVERRIDE;
62 : virtual void showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const SAL_OVERRIDE;
63 : virtual void frameIsMapping( X11SalFrame* pFrame ) const SAL_OVERRIDE;
64 : virtual void setFrameStruts( X11SalFrame* pFrame,
65 : int left, int right, int top, int bottom,
66 : int left_start_y, int left_end_y,
67 : int right_start_y, int right_end_y,
68 : int top_start_x, int top_end_x,
69 : int bottom_start_x, int bottom_end_x ) const SAL_OVERRIDE;
70 : virtual void setUserTime( X11SalFrame* i_pFrame, long i_nUserTime ) const SAL_OVERRIDE;
71 : };
72 :
73 : class GnomeWMAdaptor : public WMAdaptor
74 : {
75 : bool m_bValid;
76 :
77 : void setGnomeWMState( X11SalFrame* pFrame ) const;
78 : void initAtoms();
79 : virtual bool isValid() const SAL_OVERRIDE;
80 : public:
81 : GnomeWMAdaptor( SalDisplay * );
82 : virtual ~GnomeWMAdaptor();
83 :
84 : virtual void maximizeFrame( X11SalFrame* pFrame, bool bHorizontal = true, bool bVertical = true ) const SAL_OVERRIDE;
85 : virtual void shade( X11SalFrame* pFrame, bool bToShaded ) const SAL_OVERRIDE;
86 : virtual void enableAlwaysOnTop( X11SalFrame* pFrame, bool bEnable ) const SAL_OVERRIDE;
87 : virtual int handlePropertyNotify( X11SalFrame* pFrame, XPropertyEvent* pEvent ) const SAL_OVERRIDE;
88 : };
89 :
90 : }
91 :
92 : using namespace vcl_sal;
93 :
94 : struct WMAdaptorProtocol
95 : {
96 : const char* pProtocol;
97 : int nProtocol;
98 : };
99 :
100 : /*
101 : * table must be sorted ascending in strings
102 : * since it is use with bsearch
103 : */
104 : static const WMAdaptorProtocol aProtocolTab[] =
105 : {
106 : { "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", WMAdaptor::KDE_NET_WM_WINDOW_TYPE_OVERRIDE },
107 : { "_NET_CURRENT_DESKTOP", WMAdaptor::NET_CURRENT_DESKTOP },
108 : { "_NET_NUMBER_OF_DESKTOPS", WMAdaptor::NET_NUMBER_OF_DESKTOPS },
109 : { "_NET_WM_DESKTOP", WMAdaptor::NET_WM_DESKTOP },
110 : { "_NET_WM_ICON", WMAdaptor::NET_WM_ICON },
111 : { "_NET_WM_ICON_NAME", WMAdaptor::NET_WM_ICON_NAME },
112 : { "_NET_WM_PING", WMAdaptor::NET_WM_PING },
113 : { "_NET_WM_STATE", WMAdaptor::NET_WM_STATE },
114 : { "_NET_WM_STATE_ABOVE", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP },
115 : { "_NET_WM_STATE_FULLSCREEN", WMAdaptor::NET_WM_STATE_FULLSCREEN },
116 : { "_NET_WM_STATE_MAXIMIZED_HORIZ", WMAdaptor::NET_WM_STATE_MAXIMIZED_HORZ }, // common bug in e.g. older kwin and sawfish implementations
117 : { "_NET_WM_STATE_MAXIMIZED_HORZ", WMAdaptor::NET_WM_STATE_MAXIMIZED_HORZ },
118 : { "_NET_WM_STATE_MAXIMIZED_VERT", WMAdaptor::NET_WM_STATE_MAXIMIZED_VERT },
119 : { "_NET_WM_STATE_MODAL", WMAdaptor::NET_WM_STATE_MODAL },
120 : { "_NET_WM_STATE_SHADED", WMAdaptor::NET_WM_STATE_SHADED },
121 : { "_NET_WM_STATE_SKIP_PAGER", WMAdaptor::NET_WM_STATE_SKIP_PAGER },
122 : { "_NET_WM_STATE_SKIP_TASKBAR", WMAdaptor::NET_WM_STATE_SKIP_TASKBAR },
123 : { "_NET_WM_STATE_STAYS_ON_TOP", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP },
124 : { "_NET_WM_STATE_STICKY", WMAdaptor::NET_WM_STATE_STICKY },
125 : { "_NET_WM_STRUT", WMAdaptor::NET_WM_STRUT },
126 : { "_NET_WM_STRUT_PARTIAL", WMAdaptor::NET_WM_STRUT_PARTIAL },
127 : { "_NET_WM_WINDOW_TYPE", WMAdaptor::NET_WM_WINDOW_TYPE },
128 : { "_NET_WM_WINDOW_TYPE_DESKTOP", WMAdaptor::NET_WM_WINDOW_TYPE_DESKTOP },
129 : { "_NET_WM_WINDOW_TYPE_DIALOG", WMAdaptor::NET_WM_WINDOW_TYPE_DIALOG },
130 : { "_NET_WM_WINDOW_TYPE_DOCK", WMAdaptor::NET_WM_WINDOW_TYPE_DOCK },
131 : { "_NET_WM_WINDOW_TYPE_MENU", WMAdaptor::NET_WM_WINDOW_TYPE_MENU },
132 : { "_NET_WM_WINDOW_TYPE_NORMAL", WMAdaptor::NET_WM_WINDOW_TYPE_NORMAL },
133 : { "_NET_WM_WINDOW_TYPE_SPLASH", WMAdaptor::NET_WM_WINDOW_TYPE_SPLASH },
134 : { "_NET_WM_WINDOW_TYPE_SPLASHSCREEN", WMAdaptor::NET_WM_WINDOW_TYPE_SPLASH }, // bug in Metacity 2.4.1
135 : { "_NET_WM_WINDOW_TYPE_TOOLBAR", WMAdaptor::NET_WM_WINDOW_TYPE_TOOLBAR },
136 : { "_NET_WM_WINDOW_TYPE_UTILITY", WMAdaptor::NET_WM_WINDOW_TYPE_UTILITY },
137 : { "_NET_WORKAREA", WMAdaptor::NET_WORKAREA },
138 : { "_WIN_APP_STATE", WMAdaptor::WIN_APP_STATE },
139 : { "_WIN_CLIENT_LIST", WMAdaptor::WIN_CLIENT_LIST },
140 : { "_WIN_EXPANDED_SIZE", WMAdaptor::WIN_EXPANDED_SIZE },
141 : { "_WIN_HINTS", WMAdaptor::WIN_HINTS },
142 : { "_WIN_ICONS", WMAdaptor::WIN_ICONS },
143 : { "_WIN_LAYER", WMAdaptor::WIN_LAYER },
144 : { "_WIN_STATE", WMAdaptor::WIN_STATE },
145 : { "_WIN_WORKSPACE", WMAdaptor::WIN_WORKSPACE },
146 : { "_WIN_WORKSPACE_COUNT", WMAdaptor::WIN_WORKSPACE_COUNT }
147 : };
148 :
149 : /*
150 : * table containing atoms to get anyway
151 : */
152 :
153 : static const WMAdaptorProtocol aAtomTab[] =
154 : {
155 : { "WM_STATE", WMAdaptor::WM_STATE },
156 : { "_MOTIF_WM_HINTS", WMAdaptor::MOTIF_WM_HINTS },
157 : { "WM_PROTOCOLS", WMAdaptor::WM_PROTOCOLS },
158 : { "WM_DELETE_WINDOW", WMAdaptor::WM_DELETE_WINDOW },
159 : { "WM_TAKE_FOCUS", WMAdaptor::WM_TAKE_FOCUS },
160 : { "WM_COMMAND", WMAdaptor::WM_COMMAND },
161 : { "WM_CLIENT_LEADER", WMAdaptor::WM_CLIENT_LEADER },
162 : { "WM_LOCALE_NAME", WMAdaptor::WM_LOCALE_NAME },
163 : { "WM_TRANSIENT_FOR", WMAdaptor::WM_TRANSIENT_FOR },
164 : { "SAL_QUITEVENT", WMAdaptor::SAL_QUITEVENT },
165 : { "SAL_USEREVENT", WMAdaptor::SAL_USEREVENT },
166 : { "SAL_EXTTEXTEVENT", WMAdaptor::SAL_EXTTEXTEVENT },
167 : { "SAL_GETTIMEEVENT", WMAdaptor::SAL_GETTIMEEVENT },
168 : { "VCL_SYSTEM_SETTINGS", WMAdaptor::VCL_SYSTEM_SETTINGS },
169 : { "_XSETTINGS_SETTINGS", WMAdaptor::XSETTINGS },
170 : { "_XEMBED", WMAdaptor::XEMBED },
171 : { "_XEMBED_INFO", WMAdaptor::XEMBED_INFO },
172 : { "_NET_WM_USER_TIME", WMAdaptor::NET_WM_USER_TIME },
173 : { "_NET_WM_PID", WMAdaptor::NET_WM_PID }
174 : };
175 :
176 : extern "C" {
177 0 : static int compareProtocol( const void* pLeft, const void* pRight )
178 : {
179 0 : return strcmp( ((const WMAdaptorProtocol*)pLeft)->pProtocol, ((const WMAdaptorProtocol*)pRight)->pProtocol );
180 : }
181 : }
182 :
183 0 : WMAdaptor* WMAdaptor::createWMAdaptor( SalDisplay* pSalDisplay )
184 : {
185 0 : WMAdaptor* pAdaptor = NULL;
186 :
187 : // try a NetWM
188 0 : pAdaptor = new NetWMAdaptor( pSalDisplay );
189 0 : if( ! pAdaptor->isValid() )
190 0 : delete pAdaptor, pAdaptor = NULL;
191 : #if OSL_DEBUG_LEVEL > 1
192 : else
193 : fprintf( stderr, "WM supports extended WM hints\n" );
194 : #endif
195 :
196 : // try a GnomeWM
197 0 : if( ! pAdaptor )
198 : {
199 0 : pAdaptor = new GnomeWMAdaptor( pSalDisplay );
200 0 : if( ! pAdaptor->isValid() )
201 0 : delete pAdaptor, pAdaptor = NULL;
202 : #if OSL_DEBUG_LEVEL > 1
203 : else
204 : fprintf( stderr, "WM supports GNOME WM hints\n" );
205 : #endif
206 : }
207 :
208 0 : if( ! pAdaptor )
209 0 : pAdaptor = new WMAdaptor( pSalDisplay );
210 :
211 : #if OSL_DEBUG_LEVEL > 1
212 : fprintf(stderr, "Window Manager's name is \"%s\"\n",
213 : OUStringToOString(pAdaptor->getWindowManagerName(),
214 : RTL_TEXTENCODING_UTF8).getStr());
215 : #endif
216 0 : return pAdaptor;
217 : }
218 :
219 : /*
220 : * WMAdaptor constructor
221 : */
222 :
223 0 : WMAdaptor::WMAdaptor( SalDisplay* pDisplay ) :
224 : m_pSalDisplay( pDisplay ),
225 : m_bTransientBehaviour( true ),
226 : m_bEnableAlwaysOnTopWorks( false ),
227 : m_bLegacyPartialFullscreen( false ),
228 : m_nWinGravity( StaticGravity ),
229 : m_nInitWinGravity( StaticGravity ),
230 : m_bWMshouldSwitchWorkspace( true ),
231 0 : m_bWMshouldSwitchWorkspaceInit( false )
232 : {
233 0 : Atom aRealType = None;
234 0 : int nFormat = 8;
235 0 : unsigned long nItems = 0;
236 0 : unsigned long nBytesLeft = 0;
237 0 : unsigned char* pProperty = NULL;
238 :
239 : // default desktops
240 0 : m_nDesktops = 1;
241 0 : m_aWMWorkAreas = ::std::vector< Rectangle >
242 0 : ( 1, Rectangle( Point(), m_pSalDisplay->GetScreenSize( m_pSalDisplay->GetDefaultXScreen() ) ) );
243 0 : m_bEqualWorkAreas = true;
244 :
245 0 : memset( m_aWMAtoms, 0, sizeof( m_aWMAtoms ) );
246 0 : m_pDisplay = m_pSalDisplay->GetDisplay();
247 :
248 0 : initAtoms();
249 0 : getNetWmName(); // try to discover e.g. Sawfish
250 :
251 0 : if( m_aWMName.isEmpty() )
252 : {
253 : // check for ReflectionX wm (as it needs a workaround in Windows mode
254 0 : Atom aRwmRunning = XInternAtom( m_pDisplay, "RWM_RUNNING", True );
255 0 : if( aRwmRunning != None &&
256 : XGetWindowProperty( m_pDisplay,
257 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
258 : aRwmRunning,
259 : 0, 32,
260 : False,
261 : aRwmRunning,
262 : &aRealType,
263 : &nFormat,
264 : &nItems,
265 : &nBytesLeft,
266 0 : &pProperty ) == 0 )
267 : {
268 0 : if( aRealType == aRwmRunning )
269 0 : m_aWMName = "ReflectionX";
270 0 : XFree( pProperty );
271 : }
272 0 : else if( (aRwmRunning = XInternAtom( m_pDisplay, "_WRQ_WM_RUNNING", True )) != None &&
273 : XGetWindowProperty( m_pDisplay,
274 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
275 : aRwmRunning,
276 : 0, 32,
277 : False,
278 : XA_STRING,
279 : &aRealType,
280 : &nFormat,
281 : &nItems,
282 : &nBytesLeft,
283 0 : &pProperty ) == 0 )
284 : {
285 0 : if( aRealType == XA_STRING )
286 0 : m_aWMName = "ReflectionX Windows";
287 0 : XFree( pProperty );
288 : }
289 : }
290 0 : if( m_aWMName.isEmpty() )
291 : {
292 0 : Atom aTTAPlatform = XInternAtom( m_pDisplay, "TTA_CLIENT_PLATFORM", True );
293 0 : if( aTTAPlatform != None &&
294 : XGetWindowProperty( m_pDisplay,
295 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
296 : aTTAPlatform,
297 : 0, 32,
298 : False,
299 : XA_STRING,
300 : &aRealType,
301 : &nFormat,
302 : &nItems,
303 : &nBytesLeft,
304 0 : &pProperty ) == 0 )
305 : {
306 0 : if( aRealType == XA_STRING )
307 : {
308 0 : m_aWMName = "Tarantella";
309 : // #i62319# pretend that AlwaysOnTop works since
310 : // the alwaysontop workaround in salframe.cxx results
311 : // in a raise/lower loop on a Windows tarantella client
312 : // FIXME: this property contains an identification string that
313 : // in theory should be good enough to recognize running on a
314 : // Windows client; however this string does not seem to be
315 : // documented as well as the property itself.
316 0 : m_bEnableAlwaysOnTopWorks = true;
317 : }
318 0 : XFree( pProperty );
319 : }
320 : }
321 0 : }
322 :
323 : /*
324 : * WMAdaptor destructor
325 : */
326 :
327 0 : WMAdaptor::~WMAdaptor()
328 : {
329 0 : }
330 :
331 : /*
332 : * NetWMAdaptor constructor
333 : */
334 :
335 0 : NetWMAdaptor::NetWMAdaptor( SalDisplay* pSalDisplay ) :
336 0 : WMAdaptor( pSalDisplay )
337 : {
338 : // currently all _NET WMs do transient like expected
339 0 : m_bTransientBehaviour = true;
340 :
341 0 : Atom aRealType = None;
342 0 : int nFormat = 8;
343 0 : unsigned long nItems = 0;
344 0 : unsigned long nBytesLeft = 0;
345 0 : unsigned char* pProperty = NULL;
346 :
347 0 : initAtoms();
348 :
349 : // check for NetWM
350 0 : bool bNetWM = getNetWmName();
351 0 : if( bNetWM
352 0 : && XGetWindowProperty( m_pDisplay,
353 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
354 : m_aWMAtoms[ NET_SUPPORTED ],
355 : 0, 0,
356 : False,
357 : XA_ATOM,
358 : &aRealType,
359 : &nFormat,
360 : &nItems,
361 : &nBytesLeft,
362 0 : &pProperty ) == 0
363 0 : && aRealType == XA_ATOM
364 0 : && nFormat == 32
365 : )
366 : {
367 0 : if( pProperty )
368 : {
369 0 : XFree( pProperty );
370 0 : pProperty = NULL;
371 : }
372 : // collect supported protocols
373 0 : if( XGetWindowProperty( m_pDisplay,
374 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
375 : m_aWMAtoms[ NET_SUPPORTED ],
376 0 : 0, nBytesLeft/4,
377 : False,
378 : XA_ATOM,
379 : &aRealType,
380 : &nFormat,
381 : &nItems,
382 : &nBytesLeft,
383 0 : &pProperty ) == 0
384 0 : && nItems
385 : )
386 : {
387 0 : Atom* pAtoms = (Atom*)pProperty;
388 0 : char** pAtomNames = (char**)alloca( sizeof(char*)*nItems );
389 0 : if( XGetAtomNames( m_pDisplay, pAtoms, nItems, pAtomNames ) )
390 : {
391 : #if OSL_DEBUG_LEVEL > 1
392 : fprintf( stderr, "supported protocols:\n" );
393 : #endif
394 0 : for( unsigned int i = 0; i < nItems; i++ )
395 : {
396 : // #i80971# protect against invalid atoms
397 0 : if( pAtomNames[i] == NULL )
398 0 : continue;
399 :
400 : WMAdaptorProtocol aSearch;
401 0 : aSearch.pProtocol = pAtomNames[i];
402 : WMAdaptorProtocol* pMatch = (WMAdaptorProtocol*)
403 : bsearch( &aSearch,
404 : aProtocolTab,
405 : SAL_N_ELEMENTS( aProtocolTab ),
406 : sizeof( struct WMAdaptorProtocol ),
407 0 : compareProtocol );
408 0 : if( pMatch )
409 : {
410 0 : m_aWMAtoms[ pMatch->nProtocol ] = pAtoms[ i ];
411 0 : if( pMatch->nProtocol == NET_WM_STATE_STAYS_ON_TOP )
412 0 : m_bEnableAlwaysOnTopWorks = true;
413 : }
414 : #if OSL_DEBUG_LEVEL > 1
415 : fprintf( stderr, " %s%s\n", pAtomNames[i], ((pMatch)&&(pMatch->nProtocol != -1)) ? "" : " (unsupported)" );
416 : #endif
417 0 : XFree( pAtomNames[i] );
418 : }
419 : }
420 0 : XFree( pProperty );
421 0 : pProperty = NULL;
422 : }
423 0 : else if( pProperty )
424 : {
425 0 : XFree( pProperty );
426 0 : pProperty = NULL;
427 : }
428 :
429 : // get number of desktops
430 0 : if( m_aWMAtoms[ NET_NUMBER_OF_DESKTOPS ]
431 0 : && XGetWindowProperty( m_pDisplay,
432 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
433 : m_aWMAtoms[ NET_NUMBER_OF_DESKTOPS ],
434 : 0, 1,
435 : False,
436 : XA_CARDINAL,
437 : &aRealType,
438 : &nFormat,
439 : &nItems,
440 : &nBytesLeft,
441 0 : &pProperty ) == 0
442 0 : && pProperty
443 : )
444 : {
445 0 : m_nDesktops = *(long*)pProperty;
446 0 : XFree( pProperty );
447 0 : pProperty = NULL;
448 : // get work areas
449 0 : if( m_aWMAtoms[ NET_WORKAREA ]
450 0 : && XGetWindowProperty( m_pDisplay,
451 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
452 : m_aWMAtoms[ NET_WORKAREA ],
453 0 : 0, 4*m_nDesktops,
454 : False,
455 : XA_CARDINAL,
456 : &aRealType,
457 : &nFormat,
458 : &nItems,
459 : &nBytesLeft,
460 : &pProperty
461 0 : ) == 0
462 0 : && nItems == 4*(unsigned)m_nDesktops
463 : )
464 : {
465 0 : m_aWMWorkAreas = ::std::vector< Rectangle > ( m_nDesktops );
466 0 : long* pValues = (long*)pProperty;
467 0 : for( int i = 0; i < m_nDesktops; i++ )
468 : {
469 0 : Point aPoint( pValues[4*i],
470 0 : pValues[4*i+1] );
471 0 : Size aSize( pValues[4*i+2],
472 0 : pValues[4*i+3] );
473 0 : Rectangle aWorkArea( aPoint, aSize );
474 0 : m_aWMWorkAreas[i] = aWorkArea;
475 0 : if( aWorkArea != m_aWMWorkAreas[0] )
476 0 : m_bEqualWorkAreas = false;
477 : #if OSL_DEBUG_LEVEL > 1
478 : fprintf( stderr, "workarea %d: %ldx%ld+%ld+%ld\n",
479 : i,
480 : m_aWMWorkAreas[i].GetWidth(),
481 : m_aWMWorkAreas[i].GetHeight(),
482 : m_aWMWorkAreas[i].Left(),
483 : m_aWMWorkAreas[i].Top() );
484 : #endif
485 : }
486 0 : XFree( pProperty );
487 : }
488 : else
489 : {
490 : #if OSL_DEBUG_LEVEL > 1
491 : fprintf( stderr, "%ld workareas for %d desktops !\n", nItems/4, m_nDesktops );
492 : #endif
493 0 : if( pProperty )
494 : {
495 0 : XFree(pProperty);
496 0 : pProperty = NULL;
497 : }
498 : }
499 : }
500 0 : else if( pProperty )
501 : {
502 0 : XFree( pProperty );
503 0 : pProperty = NULL;
504 : }
505 : }
506 0 : else if( pProperty )
507 : {
508 0 : XFree( pProperty );
509 0 : pProperty = NULL;
510 : }
511 0 : }
512 :
513 : /*
514 : * NetWMAdaptor destructor
515 : */
516 0 : NetWMAdaptor::~NetWMAdaptor()
517 : {
518 0 : }
519 :
520 : /*
521 : * GnomeWMAdaptor constructor
522 : */
523 :
524 0 : GnomeWMAdaptor::GnomeWMAdaptor( SalDisplay* pSalDisplay ) :
525 : WMAdaptor( pSalDisplay ),
526 0 : m_bValid( false )
527 : {
528 : // currently all Gnome WMs do transient like expected
529 0 : m_bTransientBehaviour = true;
530 :
531 0 : Atom aRealType = None;
532 0 : int nFormat = 8;
533 0 : unsigned long nItems = 0;
534 0 : unsigned long nBytesLeft = 0;
535 0 : unsigned char* pProperty = NULL;
536 :
537 0 : initAtoms();
538 :
539 : // check for GnomeWM
540 0 : if( m_aWMAtoms[ WIN_SUPPORTING_WM_CHECK ] && m_aWMAtoms[ WIN_PROTOCOLS ] )
541 : {
542 0 : XLIB_Window aWMChild = None;
543 0 : if( XGetWindowProperty( m_pDisplay,
544 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
545 : m_aWMAtoms[ WIN_SUPPORTING_WM_CHECK ],
546 : 0, 1,
547 : False,
548 : XA_CARDINAL,
549 : &aRealType,
550 : &nFormat,
551 : &nItems,
552 : &nBytesLeft,
553 0 : &pProperty ) == 0
554 0 : && aRealType == XA_CARDINAL
555 0 : && nFormat == 32
556 0 : && nItems != 0
557 : )
558 : {
559 0 : aWMChild = *(XLIB_Window*)pProperty;
560 0 : XFree( pProperty );
561 0 : pProperty = NULL;
562 0 : XLIB_Window aCheckWindow = None;
563 0 : GetGenericData()->ErrorTrapPush();
564 0 : if( XGetWindowProperty( m_pDisplay,
565 : aWMChild,
566 : m_aWMAtoms[ WIN_SUPPORTING_WM_CHECK ],
567 : 0, 1,
568 : False,
569 : XA_CARDINAL,
570 : &aRealType,
571 : &nFormat,
572 : &nItems,
573 : &nBytesLeft,
574 0 : &pProperty ) == 0
575 0 : && aRealType == XA_CARDINAL
576 0 : && nFormat == 32
577 0 : && nItems != 0 )
578 : {
579 0 : if (! GetGenericData()->ErrorTrapPop( false ) )
580 : {
581 0 : GetGenericData()->ErrorTrapPush();
582 :
583 0 : aCheckWindow = *(XLIB_Window*)pProperty;
584 0 : XFree( pProperty );
585 0 : pProperty = NULL;
586 0 : if( aCheckWindow == aWMChild )
587 : {
588 0 : m_bValid = true;
589 : /*
590 : * get name of WM
591 : * this is NOT part of the GNOME WM hints, but e.g. Sawfish
592 : * already supports this part of the extended WM hints
593 : */
594 0 : m_aWMAtoms[ UTF8_STRING ] = XInternAtom( m_pDisplay, "UTF8_STRING", False );
595 0 : getNetWmName();
596 : }
597 : }
598 : else
599 0 : GetGenericData()->ErrorTrapPush();
600 : }
601 0 : GetGenericData()->ErrorTrapPop();
602 : }
603 0 : else if( pProperty )
604 : {
605 0 : XFree( pProperty );
606 0 : pProperty = NULL;
607 : }
608 : }
609 0 : if( m_bValid
610 0 : && XGetWindowProperty( m_pDisplay,
611 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
612 : m_aWMAtoms[ WIN_PROTOCOLS ],
613 : 0, 0,
614 : False,
615 : XA_ATOM,
616 : &aRealType,
617 : &nFormat,
618 : &nItems,
619 : &nBytesLeft,
620 0 : &pProperty ) == 0
621 0 : && aRealType == XA_ATOM
622 0 : && nFormat == 32
623 : )
624 : {
625 0 : if( pProperty )
626 : {
627 0 : XFree( pProperty );
628 0 : pProperty = NULL;
629 : }
630 : // collect supported protocols
631 0 : if( XGetWindowProperty( m_pDisplay,
632 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
633 : m_aWMAtoms[ WIN_PROTOCOLS ],
634 0 : 0, nBytesLeft/4,
635 : False,
636 : XA_ATOM,
637 : &aRealType,
638 : &nFormat,
639 : &nItems,
640 : &nBytesLeft,
641 0 : &pProperty ) == 0
642 0 : && pProperty
643 : )
644 : {
645 0 : Atom* pAtoms = (Atom*)pProperty;
646 0 : char** pAtomNames = (char**)alloca( sizeof(char*)*nItems );
647 0 : if( XGetAtomNames( m_pDisplay, pAtoms, nItems, pAtomNames ) )
648 : {
649 : #if OSL_DEBUG_LEVEL > 1
650 : fprintf( stderr, "supported protocols:\n" );
651 : #endif
652 0 : for( unsigned int i = 0; i < nItems; i++ )
653 : {
654 : // #i80971# protect against invalid atoms
655 0 : if( pAtomNames[i] == NULL )
656 0 : continue;
657 :
658 : WMAdaptorProtocol aSearch;
659 0 : aSearch.pProtocol = pAtomNames[i];
660 : WMAdaptorProtocol* pMatch = (WMAdaptorProtocol*)
661 : bsearch( &aSearch,
662 : aProtocolTab,
663 : SAL_N_ELEMENTS( aProtocolTab ),
664 : sizeof( struct WMAdaptorProtocol ),
665 0 : compareProtocol );
666 0 : if( pMatch )
667 : {
668 0 : m_aWMAtoms[ pMatch->nProtocol ] = pAtoms[ i ];
669 0 : if( pMatch->nProtocol == WIN_LAYER )
670 0 : m_bEnableAlwaysOnTopWorks = true;
671 : }
672 0 : if( strncmp( "_ICEWM_TRAY", pAtomNames[i], 11 ) == 0 )
673 : {
674 0 : m_aWMName = "IceWM";
675 0 : m_nWinGravity = NorthWestGravity;
676 0 : m_nInitWinGravity = NorthWestGravity;
677 : }
678 : #if OSL_DEBUG_LEVEL > 1
679 : fprintf( stderr, " %s%s\n", pAtomNames[i], ((pMatch) && (pMatch->nProtocol != -1)) ? "" : " (unsupported)" );
680 : #endif
681 0 : XFree( pAtomNames[i] );
682 : }
683 : }
684 0 : XFree( pProperty );
685 0 : pProperty = NULL;
686 : }
687 0 : else if( pProperty )
688 : {
689 0 : XFree( pProperty );
690 0 : pProperty = NULL;
691 : }
692 :
693 : // get number of desktops
694 0 : if( m_aWMAtoms[ WIN_WORKSPACE_COUNT ]
695 0 : && XGetWindowProperty( m_pDisplay,
696 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
697 : m_aWMAtoms[ WIN_WORKSPACE_COUNT ],
698 : 0, 1,
699 : False,
700 : XA_CARDINAL,
701 : &aRealType,
702 : &nFormat,
703 : &nItems,
704 : &nBytesLeft,
705 0 : &pProperty ) == 0
706 0 : && pProperty
707 : )
708 : {
709 0 : m_nDesktops = *(long*)pProperty;
710 0 : XFree( pProperty );
711 0 : pProperty = NULL;
712 : }
713 0 : else if( pProperty )
714 : {
715 0 : XFree( pProperty );
716 0 : pProperty = NULL;
717 : }
718 : }
719 0 : else if( pProperty )
720 : {
721 0 : XFree( pProperty );
722 0 : pProperty = NULL;
723 : }
724 0 : }
725 :
726 : /*
727 : * GnomeWMAdaptor destructor
728 : */
729 0 : GnomeWMAdaptor::~GnomeWMAdaptor()
730 : {
731 0 : }
732 :
733 : /*
734 : * getNetWmName()
735 : */
736 0 : bool WMAdaptor::getNetWmName()
737 : {
738 0 : Atom aRealType = None;
739 0 : int nFormat = 8;
740 0 : unsigned long nItems = 0;
741 0 : unsigned long nBytesLeft = 0;
742 0 : unsigned char* pProperty = NULL;
743 0 : bool bNetWM = false;
744 :
745 0 : if( m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ] && m_aWMAtoms[ NET_WM_NAME ] )
746 : {
747 0 : XLIB_Window aWMChild = None;
748 0 : if( XGetWindowProperty( m_pDisplay,
749 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
750 : m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ],
751 : 0, 1,
752 : False,
753 : XA_WINDOW,
754 : &aRealType,
755 : &nFormat,
756 : &nItems,
757 : &nBytesLeft,
758 0 : &pProperty ) == 0
759 0 : && aRealType == XA_WINDOW
760 0 : && nFormat == 32
761 0 : && nItems != 0
762 : )
763 : {
764 0 : aWMChild = *(XLIB_Window*)pProperty;
765 0 : XFree( pProperty );
766 0 : pProperty = NULL;
767 0 : XLIB_Window aCheckWindow = None;
768 0 : GetGenericData()->ErrorTrapPush();
769 0 : if( XGetWindowProperty( m_pDisplay,
770 : aWMChild,
771 : m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ],
772 : 0, 1,
773 : False,
774 : XA_WINDOW,
775 : &aRealType,
776 : &nFormat,
777 : &nItems,
778 : &nBytesLeft,
779 0 : &pProperty ) == 0
780 0 : && aRealType == XA_WINDOW
781 0 : && nFormat == 32
782 0 : && nItems != 0 )
783 : {
784 0 : if ( ! GetGenericData()->ErrorTrapPop( false ) )
785 : {
786 0 : GetGenericData()->ErrorTrapPush();
787 0 : aCheckWindow = *(XLIB_Window*)pProperty;
788 0 : XFree( pProperty );
789 0 : pProperty = NULL;
790 0 : if( aCheckWindow == aWMChild )
791 : {
792 0 : bNetWM = true;
793 : // get name of WM
794 0 : m_aWMAtoms[ UTF8_STRING ] = XInternAtom( m_pDisplay, "UTF8_STRING", False );
795 0 : if( XGetWindowProperty( m_pDisplay,
796 : aWMChild,
797 : m_aWMAtoms[ NET_WM_NAME ],
798 : 0, 256,
799 : False,
800 : AnyPropertyType, /* m_aWMAtoms[ UTF8_STRING ],*/
801 : &aRealType,
802 : &nFormat,
803 : &nItems,
804 : &nBytesLeft,
805 0 : &pProperty ) == 0
806 0 : && nItems != 0
807 : )
808 : {
809 0 : if (aRealType == m_aWMAtoms[ UTF8_STRING ])
810 0 : m_aWMName = OUString( (sal_Char*)pProperty, nItems, RTL_TEXTENCODING_UTF8 );
811 0 : else if (aRealType == XA_STRING)
812 0 : m_aWMName = OUString( (sal_Char*)pProperty, nItems, RTL_TEXTENCODING_ISO_8859_1 );
813 :
814 0 : XFree( pProperty );
815 0 : pProperty = NULL;
816 : }
817 0 : else if( pProperty )
818 : {
819 0 : XFree( pProperty );
820 0 : pProperty = NULL;
821 : }
822 :
823 : // if this is metacity, check for version to enable a legacy workaround
824 0 : if( m_aWMName.equalsAscii( "Metacity" ) )
825 : {
826 0 : int nVersionMajor = 0, nVersionMinor = 0;
827 0 : Atom nVersionAtom = XInternAtom( m_pDisplay, "_METACITY_VERSION", True );
828 0 : if( nVersionAtom )
829 : {
830 0 : if( XGetWindowProperty( m_pDisplay,
831 : aWMChild,
832 : nVersionAtom,
833 : 0, 256,
834 : False,
835 : m_aWMAtoms[ UTF8_STRING ],
836 : &aRealType,
837 : &nFormat,
838 : &nItems,
839 : &nBytesLeft,
840 0 : &pProperty ) == 0
841 0 : && nItems != 0
842 : )
843 : {
844 0 : OUString aMetaVersion( (sal_Char*)pProperty, nItems, RTL_TEXTENCODING_UTF8 );
845 0 : nVersionMajor = aMetaVersion.getToken(0, '.').toInt32();
846 0 : nVersionMinor = aMetaVersion.getToken(1, '.').toInt32();
847 : }
848 0 : if( pProperty )
849 : {
850 0 : XFree( pProperty );
851 0 : pProperty = NULL;
852 : }
853 : }
854 0 : if( nVersionMajor < 2 || (nVersionMajor == 2 && nVersionMinor < 12) )
855 0 : m_bLegacyPartialFullscreen = true;
856 : }
857 : }
858 : }
859 : else
860 : {
861 0 : if( pProperty )
862 : {
863 0 : XFree( pProperty );
864 0 : pProperty = NULL;
865 : }
866 0 : GetGenericData()->ErrorTrapPush();
867 : }
868 : }
869 :
870 0 : GetGenericData()->ErrorTrapPop();
871 : }
872 0 : else if( pProperty )
873 : {
874 0 : XFree( pProperty );
875 0 : pProperty = NULL;
876 : }
877 : }
878 0 : return bNetWM;
879 : }
880 :
881 0 : bool WMAdaptor::getWMshouldSwitchWorkspace() const
882 : {
883 0 : if( ! m_bWMshouldSwitchWorkspaceInit )
884 : {
885 0 : WMAdaptor * pWMA = const_cast<WMAdaptor*>(this);
886 :
887 0 : pWMA->m_bWMshouldSwitchWorkspace = true;
888 0 : vcl::SettingsConfigItem* pItem = vcl::SettingsConfigItem::get();
889 : OUString aSetting( pItem->getValue( OUString( "WM" ),
890 0 : OUString( "ShouldSwitchWorkspace" ) ) );
891 0 : if( aSetting.isEmpty() )
892 : {
893 0 : if( m_aWMName.equalsAscii( "awesome" ) )
894 : {
895 0 : pWMA->m_bWMshouldSwitchWorkspace = false;
896 : }
897 : }
898 : else
899 0 : pWMA->m_bWMshouldSwitchWorkspace = aSetting.toBoolean();
900 0 : pWMA->m_bWMshouldSwitchWorkspaceInit = true;
901 : }
902 0 : return m_bWMshouldSwitchWorkspace;
903 : }
904 :
905 : /*
906 : * WMAdaptor::isValid()
907 : */
908 0 : bool WMAdaptor::isValid() const
909 : {
910 0 : return true;
911 : }
912 :
913 : /*
914 : * NetWMAdaptor::isValid()
915 : */
916 0 : bool NetWMAdaptor::isValid() const
917 : {
918 : // some necessary sanity checks; there are WMs out there
919 : // which implement some of the WM hints spec without
920 : // real functionality
921 : return
922 0 : m_aWMAtoms[ NET_SUPPORTED ]
923 0 : && m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ]
924 0 : && m_aWMAtoms[ NET_WM_NAME ]
925 0 : && m_aWMAtoms[ NET_WM_WINDOW_TYPE_NORMAL ]
926 0 : && m_aWMAtoms[ NET_WM_WINDOW_TYPE_DIALOG ]
927 : ;
928 : }
929 :
930 : /*
931 : * GnomeWMAdaptor::isValid()
932 : */
933 0 : bool GnomeWMAdaptor::isValid() const
934 : {
935 0 : return m_bValid;
936 : }
937 :
938 : /*
939 : * WMAdaptor::initAtoms
940 : */
941 :
942 0 : void WMAdaptor::initAtoms()
943 : {
944 : // get basic atoms
945 0 : for( unsigned int i = 0; i < SAL_N_ELEMENTS( aAtomTab ); i++ )
946 0 : m_aWMAtoms[ aAtomTab[i].nProtocol ] = XInternAtom( m_pDisplay, aAtomTab[i].pProtocol, False );
947 0 : m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ] = XInternAtom( m_pDisplay, "_NET_SUPPORTING_WM_CHECK", True );
948 0 : m_aWMAtoms[ NET_WM_NAME ] = XInternAtom( m_pDisplay, "_NET_WM_NAME", True );
949 0 : }
950 :
951 : /*
952 : * NetWMAdaptor::initAtoms
953 : */
954 :
955 0 : void NetWMAdaptor::initAtoms()
956 : {
957 0 : WMAdaptor::initAtoms();
958 :
959 0 : m_aWMAtoms[ NET_SUPPORTED ] = XInternAtom( m_pDisplay, "_NET_SUPPORTED", True );
960 0 : }
961 :
962 : /*
963 : * GnomeWMAdaptor::initAtoms
964 : */
965 :
966 0 : void GnomeWMAdaptor::initAtoms()
967 : {
968 0 : WMAdaptor::initAtoms();
969 :
970 0 : m_aWMAtoms[ WIN_PROTOCOLS ] = XInternAtom( m_pDisplay, "_WIN_PROTOCOLS", True );
971 0 : m_aWMAtoms[ WIN_SUPPORTING_WM_CHECK ] = XInternAtom( m_pDisplay, "_WIN_SUPPORTING_WM_CHECK", True );
972 0 : }
973 :
974 : /*
975 : * WMAdaptor::setWMName
976 : * sets WM_NAME
977 : * WM_ICON_NAME
978 : */
979 :
980 0 : void WMAdaptor::setWMName( X11SalFrame* pFrame, const OUString& rWMName ) const
981 : {
982 : OString aTitle(OUStringToOString(rWMName,
983 0 : osl_getThreadTextEncoding()));
984 :
985 0 : OString aWMLocale;
986 0 : rtl_Locale* pLocale = NULL;
987 0 : osl_getProcessLocale( &pLocale );
988 0 : if( pLocale )
989 : {
990 0 : OUString aLocaleString( LanguageTag( *pLocale).getGlibcLocaleString( OUString()));
991 0 : aWMLocale = OUStringToOString( aLocaleString, RTL_TEXTENCODING_ISO_8859_1 );
992 : }
993 : else
994 : {
995 0 : static const char* pLang = getenv( "LANG" );
996 0 : aWMLocale = pLang ? pLang : "C";
997 : }
998 :
999 : static bool bTrustXmb = true;
1000 : #ifdef SOLARIS
1001 : /* #i64273# there are some weird cases when using IIIMP on Solaris
1002 : * where for unknown reasons XmbTextListToTextProperty results in
1003 : * garbage. Test one string once to ensure safety.
1004 : *
1005 : * FIXME: This must be a bug in xiiimp.so.2 somewhere. However
1006 : * it was not possible to recreate this in a small sample program.
1007 : * This reeks of memory corruption somehow.
1008 : */
1009 : static bool bOnce = true;
1010 : if( bOnce )
1011 : {
1012 : bOnce = false;
1013 : XTextProperty aTestProp = { NULL, None, 0, 0 };
1014 : const char *pText = "trustme";
1015 : char* pT = const_cast<char*>(pText);
1016 : XmbTextListToTextProperty( m_pDisplay,
1017 : &pT,
1018 : 1,
1019 : XStdICCTextStyle,
1020 : &aTestProp );
1021 : bTrustXmb = (aTestProp.nitems == 7) &&
1022 : (aTestProp.value != NULL ) &&
1023 : (strncmp( (char*)aTestProp.value, pText, 7 ) == 0) &&
1024 : (aTestProp.encoding == XA_STRING);
1025 : if( aTestProp.value )
1026 : XFree( aTestProp.value );
1027 : #if OSL_DEBUG_LEVEL > 1
1028 : fprintf( stderr, "%s\n",
1029 : bTrustXmb ?
1030 : "XmbTextListToTextProperty seems to work" :
1031 : "XmbTextListToTextProperty does not seem to work" );
1032 : #endif
1033 : }
1034 : #endif
1035 :
1036 0 : char* pT = const_cast<char*>(aTitle.getStr());
1037 0 : XTextProperty aProp = { NULL, None, 0, 0 };
1038 0 : if( bTrustXmb )
1039 : {
1040 : XmbTextListToTextProperty( m_pDisplay,
1041 : &pT,
1042 : 1,
1043 : XStdICCTextStyle,
1044 0 : &aProp );
1045 : }
1046 :
1047 0 : unsigned char* pData = aProp.nitems ? aProp.value : (unsigned char*)aTitle.getStr();
1048 0 : Atom nType = aProp.nitems ? aProp.encoding : XA_STRING;
1049 0 : int nFormat = aProp.nitems ? aProp.format : 8;
1050 0 : int nBytes = aProp.nitems ? aProp.nitems : aTitle.getLength();
1051 0 : const SystemEnvData* pEnv = pFrame->GetSystemData();
1052 : XChangeProperty( m_pDisplay,
1053 : (XLIB_Window)pEnv->aShellWindow,
1054 : XA_WM_NAME,
1055 : nType,
1056 : nFormat,
1057 : PropModeReplace,
1058 : pData,
1059 0 : nBytes );
1060 : XChangeProperty( m_pDisplay,
1061 : (XLIB_Window)pEnv->aShellWindow,
1062 : XA_WM_ICON_NAME,
1063 : nType,
1064 : nFormat,
1065 : PropModeReplace,
1066 : pData,
1067 0 : nBytes );
1068 : XChangeProperty( m_pDisplay,
1069 : (XLIB_Window)pEnv->aShellWindow,
1070 0 : m_aWMAtoms[ WM_LOCALE_NAME ],
1071 : XA_STRING,
1072 : 8,
1073 : PropModeReplace,
1074 0 : (unsigned char*)aWMLocale.getStr(),
1075 0 : aWMLocale.getLength() );
1076 0 : if (aProp.value != NULL)
1077 0 : XFree( aProp.value );
1078 0 : }
1079 :
1080 : /*
1081 : * NetWMAdaptor::setWMName
1082 : * sets WM_NAME
1083 : * _NET_WM_NAME
1084 : * WM_ICON_NAME
1085 : * _NET_WM_ICON_NAME
1086 : */
1087 0 : void NetWMAdaptor::setWMName( X11SalFrame* pFrame, const OUString& rWMName ) const
1088 : {
1089 0 : WMAdaptor::setWMName( pFrame, rWMName );
1090 :
1091 0 : OString aTitle(OUStringToOString(rWMName, RTL_TEXTENCODING_UTF8));
1092 0 : const SystemEnvData* pEnv = pFrame->GetSystemData();
1093 0 : if( m_aWMAtoms[ NET_WM_NAME ] )
1094 : XChangeProperty( m_pDisplay,
1095 : (XLIB_Window)pEnv->aShellWindow,
1096 0 : m_aWMAtoms[ NET_WM_NAME ],
1097 0 : m_aWMAtoms[ UTF8_STRING ],
1098 : 8,
1099 : PropModeReplace,
1100 0 : (unsigned char*)aTitle.getStr(),
1101 0 : aTitle.getLength() );
1102 0 : if( m_aWMAtoms[ NET_WM_ICON_NAME ] )
1103 : XChangeProperty( m_pDisplay,
1104 : (XLIB_Window)pEnv->aShellWindow,
1105 0 : m_aWMAtoms[ NET_WM_ICON_NAME ],
1106 0 : m_aWMAtoms[ UTF8_STRING ],
1107 : 8,
1108 : PropModeReplace,
1109 0 : (unsigned char*)aTitle.getStr(),
1110 0 : aTitle.getLength() );
1111 0 : }
1112 :
1113 : /*
1114 : * NetWMAdaptor::setNetWMState
1115 : * sets _NET_WM_STATE
1116 : */
1117 0 : void NetWMAdaptor::setNetWMState( X11SalFrame* pFrame ) const
1118 : {
1119 0 : if( m_aWMAtoms[ NET_WM_STATE ] )
1120 : {
1121 : Atom aStateAtoms[ 10 ];
1122 0 : int nStateAtoms = 0;
1123 :
1124 : // set NET_WM_STATE_MODAL
1125 0 : if( m_aWMAtoms[ NET_WM_STATE_MODAL ]
1126 0 : && pFrame->meWindowType == windowType_ModalDialogue )
1127 : {
1128 0 : aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_MODAL ];
1129 : /*
1130 : * #90998# NET_WM_STATE_SKIP_TASKBAR set on a frame will
1131 : * cause kwin not to give it the focus on map request
1132 : * this seems to be a bug in kwin
1133 : * aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_SKIP_TASKBAR ];
1134 : */
1135 : }
1136 0 : if( pFrame->mbMaximizedVert
1137 0 : && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] )
1138 0 : aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ];
1139 0 : if( pFrame->mbMaximizedHorz
1140 0 : && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ] )
1141 0 : aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ];
1142 0 : if( pFrame->bAlwaysOnTop_ && m_aWMAtoms[ NET_WM_STATE_STAYS_ON_TOP ] )
1143 0 : aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_STAYS_ON_TOP ];
1144 0 : if( pFrame->mbShaded && m_aWMAtoms[ NET_WM_STATE_SHADED ] )
1145 0 : aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_SHADED ];
1146 0 : if( pFrame->mbFullScreen && m_aWMAtoms[ NET_WM_STATE_FULLSCREEN ] )
1147 0 : aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_FULLSCREEN ];
1148 0 : if( pFrame->meWindowType == windowType_Utility && m_aWMAtoms[ NET_WM_STATE_SKIP_TASKBAR ] )
1149 0 : aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_SKIP_TASKBAR ];
1150 :
1151 0 : if( nStateAtoms )
1152 : {
1153 : XChangeProperty( m_pDisplay,
1154 : pFrame->GetShellWindow(),
1155 0 : m_aWMAtoms[ NET_WM_STATE ],
1156 : XA_ATOM,
1157 : 32,
1158 : PropModeReplace,
1159 : (unsigned char*)aStateAtoms,
1160 : nStateAtoms
1161 0 : );
1162 : }
1163 : else
1164 : XDeleteProperty( m_pDisplay,
1165 : pFrame->GetShellWindow(),
1166 0 : m_aWMAtoms[ NET_WM_STATE ] );
1167 0 : if( pFrame->mbMaximizedHorz
1168 0 : && pFrame->mbMaximizedVert
1169 0 : && ! ( pFrame->nStyle_ & SAL_FRAME_STYLE_SIZEABLE ) )
1170 : {
1171 : /*
1172 : * for maximizing use NorthWestGravity (including decoration)
1173 : */
1174 : XSizeHints hints;
1175 : long supplied;
1176 0 : bool bHint = false;
1177 0 : if( XGetWMNormalHints( m_pDisplay,
1178 : pFrame->GetShellWindow(),
1179 : &hints,
1180 0 : &supplied ) )
1181 : {
1182 0 : bHint = true;
1183 0 : hints.flags |= PWinGravity;
1184 0 : hints.win_gravity = NorthWestGravity;
1185 : XSetWMNormalHints( m_pDisplay,
1186 : pFrame->GetShellWindow(),
1187 0 : &hints );
1188 0 : XSync( m_pDisplay, False );
1189 : }
1190 :
1191 : // SetPosSize necessary to set width/height, min/max w/h
1192 0 : sal_Int32 nCurrent = 0;
1193 : /*
1194 : * get current desktop here if work areas have different size
1195 : * (does this happen on any platform ?)
1196 : */
1197 0 : if( ! m_bEqualWorkAreas )
1198 : {
1199 0 : nCurrent = getCurrentWorkArea();
1200 0 : if( nCurrent < 0 )
1201 0 : nCurrent = 0;
1202 : }
1203 0 : Rectangle aPosSize = m_aWMWorkAreas[nCurrent];
1204 0 : const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
1205 0 : aPosSize = Rectangle( Point( aPosSize.Left() + rGeom.nLeftDecoration,
1206 0 : aPosSize.Top() + rGeom.nTopDecoration ),
1207 0 : Size( aPosSize.GetWidth()
1208 0 : - rGeom.nLeftDecoration
1209 0 : - rGeom.nRightDecoration,
1210 0 : aPosSize.GetHeight()
1211 0 : - rGeom.nTopDecoration
1212 0 : - rGeom.nBottomDecoration )
1213 0 : );
1214 0 : pFrame->SetPosSize( aPosSize );
1215 :
1216 : /*
1217 : * reset gravity hint to static gravity
1218 : * (this should not move window according to ICCCM)
1219 : */
1220 0 : if( bHint && pFrame->nShowState_ != SHOWSTATE_UNKNOWN )
1221 : {
1222 0 : hints.win_gravity = StaticGravity;
1223 : XSetWMNormalHints( m_pDisplay,
1224 : pFrame->GetShellWindow(),
1225 0 : &hints );
1226 : }
1227 : }
1228 : }
1229 0 : }
1230 :
1231 : /*
1232 : * GnomeWMAdaptor::setNetWMState
1233 : * sets _WIN_STATE
1234 : */
1235 0 : void GnomeWMAdaptor::setGnomeWMState( X11SalFrame* pFrame ) const
1236 : {
1237 0 : if( m_aWMAtoms[ WIN_STATE ] )
1238 : {
1239 0 : sal_uInt32 nWinWMState = 0;
1240 :
1241 0 : if( pFrame->mbMaximizedVert )
1242 0 : nWinWMState |= 1 << 2;
1243 0 : if( pFrame->mbMaximizedHorz )
1244 0 : nWinWMState |= 1 << 3;
1245 0 : if( pFrame->mbShaded )
1246 0 : nWinWMState |= 1 << 5;
1247 :
1248 : XChangeProperty( m_pDisplay,
1249 : pFrame->GetShellWindow(),
1250 0 : m_aWMAtoms[ WIN_STATE ],
1251 : XA_CARDINAL,
1252 : 32,
1253 : PropModeReplace,
1254 : (unsigned char*)&nWinWMState,
1255 : 1
1256 0 : );
1257 0 : if( pFrame->mbMaximizedHorz
1258 0 : && pFrame->mbMaximizedVert
1259 0 : && ! ( pFrame->nStyle_ & SAL_FRAME_STYLE_SIZEABLE ) )
1260 : {
1261 : /*
1262 : * for maximizing use NorthWestGravity (including decoration)
1263 : */
1264 : XSizeHints hints;
1265 : long supplied;
1266 0 : bool bHint = false;
1267 0 : if( XGetWMNormalHints( m_pDisplay,
1268 : pFrame->GetShellWindow(),
1269 : &hints,
1270 0 : &supplied ) )
1271 : {
1272 0 : bHint = true;
1273 0 : hints.flags |= PWinGravity;
1274 0 : hints.win_gravity = NorthWestGravity;
1275 : XSetWMNormalHints( m_pDisplay,
1276 : pFrame->GetShellWindow(),
1277 0 : &hints );
1278 0 : XSync( m_pDisplay, False );
1279 : }
1280 :
1281 : // SetPosSize necessary to set width/height, min/max w/h
1282 0 : sal_Int32 nCurrent = 0;
1283 : /*
1284 : * get current desktop here if work areas have different size
1285 : * (does this happen on any platform ?)
1286 : */
1287 0 : if( ! m_bEqualWorkAreas )
1288 : {
1289 0 : nCurrent = getCurrentWorkArea();
1290 0 : if( nCurrent < 0 )
1291 0 : nCurrent = 0;
1292 : }
1293 0 : Rectangle aPosSize = m_aWMWorkAreas[nCurrent];
1294 0 : const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
1295 0 : aPosSize = Rectangle( Point( aPosSize.Left() + rGeom.nLeftDecoration,
1296 0 : aPosSize.Top() + rGeom.nTopDecoration ),
1297 0 : Size( aPosSize.GetWidth()
1298 0 : - rGeom.nLeftDecoration
1299 0 : - rGeom.nRightDecoration,
1300 0 : aPosSize.GetHeight()
1301 0 : - rGeom.nTopDecoration
1302 0 : - rGeom.nBottomDecoration )
1303 0 : );
1304 0 : pFrame->SetPosSize( aPosSize );
1305 :
1306 : /*
1307 : * reset gravity hint to static gravity
1308 : * (this should not move window according to ICCCM)
1309 : */
1310 0 : if( bHint && pFrame->nShowState_ != SHOWSTATE_UNKNOWN )
1311 : {
1312 0 : hints.win_gravity = StaticGravity;
1313 : XSetWMNormalHints( m_pDisplay,
1314 : pFrame->GetShellWindow(),
1315 0 : &hints );
1316 : }
1317 : }
1318 : }
1319 0 : }
1320 :
1321 : /*
1322 : * WMAdaptor::setFrameDecoration
1323 : * sets _MOTIF_WM_HINTS
1324 : * WM_TRANSIENT_FOR
1325 : */
1326 :
1327 0 : void WMAdaptor::setFrameTypeAndDecoration( X11SalFrame* pFrame, WMWindowType eType, int nDecorationFlags, X11SalFrame* pReferenceFrame ) const
1328 : {
1329 0 : pFrame->meWindowType = eType;
1330 0 : pFrame->mnDecorationFlags = nDecorationFlags;
1331 :
1332 0 : if( ! pFrame->mbFullScreen )
1333 : {
1334 : // set mwm hints
1335 : struct _mwmhints {
1336 : unsigned long flags, func, deco;
1337 : long input_mode;
1338 : unsigned long status;
1339 : } aHint;
1340 :
1341 0 : aHint.flags = 15; /* flags for functions, decoration, input mode and status */
1342 0 : aHint.deco = 0;
1343 0 : aHint.func = 1L << 2;
1344 0 : aHint.status = 0;
1345 0 : aHint.input_mode = 0;
1346 :
1347 : // evaluate decoration flags
1348 0 : if( nDecorationFlags & decoration_All )
1349 0 : aHint.deco = 1, aHint.func = 1;
1350 : else
1351 : {
1352 0 : if( nDecorationFlags & decoration_Title )
1353 0 : aHint.deco |= 1L << 3;
1354 0 : if( nDecorationFlags & decoration_Border )
1355 0 : aHint.deco |= 1L << 1;
1356 0 : if( nDecorationFlags & decoration_Resize )
1357 0 : aHint.deco |= 1L << 2, aHint.func |= 1L << 1;
1358 0 : if( nDecorationFlags & decoration_MinimizeBtn )
1359 0 : aHint.deco |= 1L << 5, aHint.func |= 1L << 3;
1360 0 : if( nDecorationFlags & decoration_MaximizeBtn )
1361 0 : aHint.deco |= 1L << 6, aHint.func |= 1L << 4;
1362 0 : if( nDecorationFlags & decoration_CloseBtn )
1363 0 : aHint.deco |= 1L << 4, aHint.func |= 1L << 5;
1364 : }
1365 : // evaluate window type
1366 0 : switch( eType )
1367 : {
1368 : case windowType_ModalDialogue:
1369 0 : aHint.input_mode = 1;
1370 0 : break;
1371 : default:
1372 0 : break;
1373 : }
1374 :
1375 : // set the hint
1376 : XChangeProperty( m_pDisplay,
1377 : pFrame->GetShellWindow(),
1378 0 : m_aWMAtoms[ MOTIF_WM_HINTS ],
1379 0 : m_aWMAtoms[ MOTIF_WM_HINTS ],
1380 : 32,
1381 : PropModeReplace,
1382 : (unsigned char*)&aHint,
1383 0 : 5 );
1384 : }
1385 :
1386 : // set transientFor hint
1387 : /* #91030# dtwm will not map a dialogue if the transient
1388 : * window is iconified. This is deemed undesireable because
1389 : * message boxes do not get mapped, so use the root as transient
1390 : * instead.
1391 : */
1392 0 : if( pReferenceFrame )
1393 : {
1394 : XSetTransientForHint( m_pDisplay,
1395 : pFrame->GetShellWindow(),
1396 : pReferenceFrame->bMapped_ ?
1397 : pReferenceFrame->GetShellWindow() :
1398 0 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() )
1399 0 : );
1400 0 : if( ! pReferenceFrame->bMapped_ )
1401 0 : pFrame->mbTransientForRoot = true;
1402 : }
1403 0 : }
1404 :
1405 : /*
1406 : * NetWMAdaptor::setFrameDecoration
1407 : * sets _MOTIF_WM_HINTS
1408 : * _NET_WM_WINDOW_TYPE
1409 : * _NET_WM_STATE
1410 : * WM_TRANSIENT_FOR
1411 : */
1412 :
1413 0 : void NetWMAdaptor::setFrameTypeAndDecoration( X11SalFrame* pFrame, WMWindowType eType, int nDecorationFlags, X11SalFrame* pReferenceFrame ) const
1414 : {
1415 0 : WMAdaptor::setFrameTypeAndDecoration( pFrame, eType, nDecorationFlags, pReferenceFrame );
1416 :
1417 0 : setNetWMState( pFrame );
1418 :
1419 : // set NET_WM_WINDOW_TYPE
1420 0 : if( m_aWMAtoms[ NET_WM_WINDOW_TYPE ] )
1421 : {
1422 : Atom aWindowTypes[4];
1423 0 : int nWindowTypes = 0;
1424 0 : switch( eType )
1425 : {
1426 : case windowType_Utility:
1427 0 : aWindowTypes[nWindowTypes++] =
1428 0 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_UTILITY ] ?
1429 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_UTILITY ] :
1430 0 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_DIALOG ];
1431 0 : break;
1432 : case windowType_ModelessDialogue:
1433 : case windowType_ModalDialogue:
1434 0 : aWindowTypes[nWindowTypes++] =
1435 0 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_DIALOG ];
1436 0 : break;
1437 : case windowType_Splash:
1438 0 : aWindowTypes[nWindowTypes++] =
1439 0 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_SPLASH ] ?
1440 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_SPLASH ] :
1441 0 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_NORMAL ];
1442 0 : break;
1443 : case windowType_Toolbar:
1444 0 : if( m_aWMAtoms[ KDE_NET_WM_WINDOW_TYPE_OVERRIDE ] )
1445 0 : aWindowTypes[nWindowTypes++] = m_aWMAtoms[ KDE_NET_WM_WINDOW_TYPE_OVERRIDE ];
1446 0 : aWindowTypes[nWindowTypes++] =
1447 0 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_TOOLBAR ] ?
1448 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_TOOLBAR ] :
1449 0 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_NORMAL];
1450 0 : break;
1451 : case windowType_Dock:
1452 0 : aWindowTypes[nWindowTypes++] =
1453 0 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_DOCK ] ?
1454 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_DOCK ] :
1455 0 : m_aWMAtoms[ NET_WM_WINDOW_TYPE_NORMAL];
1456 0 : break;
1457 : default:
1458 0 : aWindowTypes[nWindowTypes++] = m_aWMAtoms[ NET_WM_WINDOW_TYPE_NORMAL ];
1459 0 : break;
1460 : }
1461 : XChangeProperty( m_pDisplay,
1462 : pFrame->GetShellWindow(),
1463 0 : m_aWMAtoms[ NET_WM_WINDOW_TYPE ],
1464 : XA_ATOM,
1465 : 32,
1466 : PropModeReplace,
1467 : (unsigned char*)aWindowTypes,
1468 0 : nWindowTypes );
1469 : }
1470 0 : if( ( eType == windowType_ModalDialogue ||
1471 : eType == windowType_ModelessDialogue )
1472 0 : && ! pReferenceFrame )
1473 : {
1474 : XSetTransientForHint( m_pDisplay,
1475 : pFrame->GetShellWindow(),
1476 0 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ) );
1477 0 : pFrame->mbTransientForRoot = true;
1478 : }
1479 0 : }
1480 :
1481 : /*
1482 : * WMAdaptor::maximizeFrame
1483 : */
1484 :
1485 0 : void WMAdaptor::maximizeFrame( X11SalFrame* pFrame, bool bHorizontal, bool bVertical ) const
1486 : {
1487 0 : pFrame->mbMaximizedVert = bVertical;
1488 0 : pFrame->mbMaximizedHorz = bHorizontal;
1489 :
1490 0 : const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
1491 :
1492 : // discard pending configure notifies for this frame
1493 0 : XSync( m_pDisplay, False );
1494 : XEvent aDiscard;
1495 0 : while( XCheckTypedWindowEvent( m_pDisplay,
1496 : pFrame->GetShellWindow(),
1497 : ConfigureNotify,
1498 0 : &aDiscard ) )
1499 : ;
1500 0 : while( XCheckTypedWindowEvent( m_pDisplay,
1501 : pFrame->GetWindow(),
1502 : ConfigureNotify,
1503 0 : &aDiscard ) )
1504 : ;
1505 :
1506 0 : if( bHorizontal || bVertical )
1507 : {
1508 0 : Size aScreenSize( m_pSalDisplay->GetScreenSize( pFrame->GetScreenNumber() ) );
1509 0 : Point aTL( rGeom.nLeftDecoration, rGeom.nTopDecoration );
1510 0 : if( m_pSalDisplay->IsXinerama() )
1511 : {
1512 0 : Point aMed( aTL.X() + rGeom.nWidth/2, aTL.Y() + rGeom.nHeight/2 );
1513 0 : const std::vector< Rectangle >& rScreens = m_pSalDisplay->GetXineramaScreens();
1514 0 : for( unsigned int i = 0; i < rScreens.size(); i++ )
1515 0 : if( rScreens[i].IsInside( aMed ) )
1516 : {
1517 0 : aTL += rScreens[i].TopLeft();
1518 0 : aScreenSize = rScreens[i].GetSize();
1519 0 : break;
1520 : }
1521 : }
1522 : Rectangle aTarget( aTL,
1523 0 : Size( aScreenSize.Width() - rGeom.nLeftDecoration - rGeom.nTopDecoration,
1524 0 : aScreenSize.Height() - rGeom.nTopDecoration - rGeom.nBottomDecoration )
1525 0 : );
1526 0 : if( ! bHorizontal )
1527 : {
1528 : aTarget.SetSize(
1529 : Size(
1530 0 : pFrame->maRestorePosSize.IsEmpty() ?
1531 0 : rGeom.nWidth : pFrame->maRestorePosSize.GetWidth(),
1532 : aTarget.GetHeight()
1533 : )
1534 0 : );
1535 0 : aTarget.Left() =
1536 0 : pFrame->maRestorePosSize.IsEmpty() ?
1537 0 : rGeom.nX : pFrame->maRestorePosSize.Left();
1538 : }
1539 0 : else if( ! bVertical )
1540 : {
1541 : aTarget.SetSize(
1542 : Size(
1543 : aTarget.GetWidth(),
1544 0 : pFrame->maRestorePosSize.IsEmpty() ?
1545 0 : rGeom.nHeight : pFrame->maRestorePosSize.GetHeight()
1546 : )
1547 0 : );
1548 0 : aTarget.Top() =
1549 0 : pFrame->maRestorePosSize.IsEmpty() ?
1550 0 : rGeom.nY : pFrame->maRestorePosSize.Top();
1551 : }
1552 :
1553 0 : Rectangle aRestore( Point( rGeom.nX, rGeom.nY ), Size( rGeom.nWidth, rGeom.nHeight ) );
1554 0 : if( pFrame->bMapped_ )
1555 : {
1556 : XSetInputFocus( m_pDisplay,
1557 : pFrame->GetShellWindow(),
1558 : RevertToNone,
1559 : CurrentTime
1560 0 : );
1561 : }
1562 :
1563 0 : if( pFrame->maRestorePosSize.IsEmpty() )
1564 0 : pFrame->maRestorePosSize = aRestore;
1565 :
1566 0 : pFrame->SetPosSize( aTarget );
1567 0 : pFrame->nWidth_ = aTarget.GetWidth();
1568 0 : pFrame->nHeight_ = aTarget.GetHeight();
1569 : XRaiseWindow( m_pDisplay,
1570 : pFrame->GetShellWindow()
1571 0 : );
1572 0 : if( pFrame->GetStackingWindow() )
1573 : XRaiseWindow( m_pDisplay,
1574 : pFrame->GetStackingWindow()
1575 0 : );
1576 :
1577 : }
1578 : else
1579 : {
1580 0 : pFrame->SetPosSize( pFrame->maRestorePosSize );
1581 0 : pFrame->maRestorePosSize = Rectangle();
1582 0 : pFrame->nWidth_ = rGeom.nWidth;
1583 0 : pFrame->nHeight_ = rGeom.nHeight;
1584 : }
1585 0 : }
1586 :
1587 : /*
1588 : * NetWMAdaptor::maximizeFrame
1589 : * changes _NET_WM_STATE by sending a client message
1590 : */
1591 :
1592 0 : void NetWMAdaptor::maximizeFrame( X11SalFrame* pFrame, bool bHorizontal, bool bVertical ) const
1593 : {
1594 0 : pFrame->mbMaximizedVert = bVertical;
1595 0 : pFrame->mbMaximizedHorz = bHorizontal;
1596 :
1597 0 : if( m_aWMAtoms[ NET_WM_STATE ]
1598 0 : && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ]
1599 0 : && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ]
1600 0 : && ( pFrame->nStyle_ & ~SAL_FRAME_STYLE_DEFAULT )
1601 : )
1602 : {
1603 0 : if( pFrame->bMapped_ )
1604 : {
1605 : // window already mapped, send WM a message
1606 : XEvent aEvent;
1607 0 : aEvent.type = ClientMessage;
1608 0 : aEvent.xclient.display = m_pDisplay;
1609 0 : aEvent.xclient.window = pFrame->GetShellWindow();
1610 0 : aEvent.xclient.message_type = m_aWMAtoms[ NET_WM_STATE ];
1611 0 : aEvent.xclient.format = 32;
1612 0 : aEvent.xclient.data.l[0] = bHorizontal ? 1 : 0;
1613 0 : aEvent.xclient.data.l[1] = m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ];
1614 0 : aEvent.xclient.data.l[2] = bHorizontal == bVertical ? m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] : 0;
1615 0 : aEvent.xclient.data.l[3] = 0;
1616 0 : aEvent.xclient.data.l[4] = 0;
1617 : XSendEvent( m_pDisplay,
1618 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
1619 : False,
1620 : SubstructureNotifyMask | SubstructureRedirectMask,
1621 : &aEvent
1622 0 : );
1623 0 : if( bHorizontal != bVertical )
1624 : {
1625 0 : aEvent.xclient.data.l[0]= bVertical ? 1 : 0;
1626 0 : aEvent.xclient.data.l[1]= m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ];
1627 0 : aEvent.xclient.data.l[2]= 0;
1628 : XSendEvent( m_pDisplay,
1629 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
1630 : False,
1631 : SubstructureNotifyMask | SubstructureRedirectMask,
1632 : &aEvent
1633 0 : );
1634 : }
1635 : }
1636 : else
1637 : {
1638 : // window not mapped yet, set _NET_WM_STATE directly
1639 0 : setNetWMState( pFrame );
1640 : }
1641 0 : if( !bHorizontal && !bVertical )
1642 0 : pFrame->maRestorePosSize = Rectangle();
1643 0 : else if( pFrame->maRestorePosSize.IsEmpty() )
1644 : {
1645 0 : const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
1646 : pFrame->maRestorePosSize =
1647 0 : Rectangle( Point( rGeom.nX, rGeom.nY ), Size( rGeom.nWidth, rGeom.nHeight ) );
1648 0 : }
1649 : }
1650 : else
1651 0 : WMAdaptor::maximizeFrame( pFrame, bHorizontal, bVertical );
1652 0 : }
1653 :
1654 : /*
1655 : * GnomeWMAdaptor::maximizeFrame
1656 : * changes _WIN_STATE by sending a client message
1657 : */
1658 :
1659 0 : void GnomeWMAdaptor::maximizeFrame( X11SalFrame* pFrame, bool bHorizontal, bool bVertical ) const
1660 : {
1661 0 : pFrame->mbMaximizedVert = bVertical;
1662 0 : pFrame->mbMaximizedHorz = bHorizontal;
1663 :
1664 0 : if( m_aWMAtoms[ WIN_STATE ]
1665 0 : && ( pFrame->nStyle_ & ~SAL_FRAME_STYLE_DEFAULT )
1666 : )
1667 : {
1668 0 : if( pFrame->bMapped_ )
1669 : {
1670 : // window already mapped, send WM a message
1671 : XEvent aEvent;
1672 0 : aEvent.type = ClientMessage;
1673 0 : aEvent.xclient.display = m_pDisplay;
1674 0 : aEvent.xclient.window = pFrame->GetShellWindow();
1675 0 : aEvent.xclient.message_type = m_aWMAtoms[ WIN_STATE ];
1676 0 : aEvent.xclient.format = 32;
1677 0 : aEvent.xclient.data.l[0] = (1<<2)|(1<<3);
1678 : aEvent.xclient.data.l[1] =
1679 : (bVertical ? (1<<2) : 0)
1680 0 : | (bHorizontal ? (1<<3) : 0);
1681 0 : aEvent.xclient.data.l[2] = 0;
1682 0 : aEvent.xclient.data.l[3] = 0;
1683 0 : aEvent.xclient.data.l[4] = 0;
1684 : XSendEvent( m_pDisplay,
1685 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
1686 : False,
1687 : SubstructureNotifyMask,
1688 : &aEvent
1689 0 : );
1690 : }
1691 : else
1692 : // window not mapped yet, set _WIN_STATE directly
1693 0 : setGnomeWMState( pFrame );
1694 :
1695 0 : if( !bHorizontal && !bVertical )
1696 0 : pFrame->maRestorePosSize = Rectangle();
1697 0 : else if( pFrame->maRestorePosSize.IsEmpty() )
1698 : {
1699 0 : const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
1700 : pFrame->maRestorePosSize =
1701 0 : Rectangle( Point( rGeom.nX, rGeom.nY ), Size( rGeom.nWidth, rGeom.nHeight ) );
1702 0 : }
1703 : }
1704 : else
1705 0 : WMAdaptor::maximizeFrame( pFrame, bHorizontal, bVertical );
1706 0 : }
1707 :
1708 : /*
1709 : * WMAdaptor::enableAlwaysOnTop
1710 : */
1711 0 : void WMAdaptor::enableAlwaysOnTop( X11SalFrame*, bool /*bEnable*/ ) const
1712 : {
1713 0 : }
1714 :
1715 : /*
1716 : * NetWMAdaptor::enableAlwaysOnTop
1717 : */
1718 0 : void NetWMAdaptor::enableAlwaysOnTop( X11SalFrame* pFrame, bool bEnable ) const
1719 : {
1720 0 : pFrame->bAlwaysOnTop_ = bEnable;
1721 0 : if( m_aWMAtoms[ NET_WM_STATE_STAYS_ON_TOP ] )
1722 : {
1723 0 : if( pFrame->bMapped_ )
1724 : {
1725 : // window already mapped, send WM a message
1726 : XEvent aEvent;
1727 0 : aEvent.type = ClientMessage;
1728 0 : aEvent.xclient.display = m_pDisplay;
1729 0 : aEvent.xclient.window = pFrame->GetShellWindow();
1730 0 : aEvent.xclient.message_type = m_aWMAtoms[ NET_WM_STATE ];
1731 0 : aEvent.xclient.format = 32;
1732 0 : aEvent.xclient.data.l[0] = bEnable ? 1 : 0;
1733 0 : aEvent.xclient.data.l[1] = m_aWMAtoms[ NET_WM_STATE_STAYS_ON_TOP ];
1734 0 : aEvent.xclient.data.l[2] = 0;
1735 0 : aEvent.xclient.data.l[3] = 0;
1736 0 : aEvent.xclient.data.l[4] = 0;
1737 : XSendEvent( m_pDisplay,
1738 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
1739 : False,
1740 : SubstructureNotifyMask | SubstructureRedirectMask,
1741 : &aEvent
1742 0 : );
1743 : }
1744 : else
1745 0 : setNetWMState( pFrame );
1746 : }
1747 0 : }
1748 :
1749 : /*
1750 : * GnomeWMAdaptor::enableAlwaysOnTop
1751 : */
1752 0 : void GnomeWMAdaptor::enableAlwaysOnTop( X11SalFrame* pFrame, bool bEnable ) const
1753 : {
1754 0 : pFrame->bAlwaysOnTop_ = bEnable;
1755 0 : if( m_aWMAtoms[ WIN_LAYER ] )
1756 : {
1757 0 : if( pFrame->bMapped_ )
1758 : {
1759 : // window already mapped, send WM a message
1760 : XEvent aEvent;
1761 0 : aEvent.type = ClientMessage;
1762 0 : aEvent.xclient.display = m_pDisplay;
1763 0 : aEvent.xclient.window = pFrame->GetShellWindow();
1764 0 : aEvent.xclient.message_type = m_aWMAtoms[ WIN_LAYER ];
1765 0 : aEvent.xclient.format = 32;
1766 0 : aEvent.xclient.data.l[0] = bEnable ? 6 : 4;
1767 0 : aEvent.xclient.data.l[1] = 0;
1768 0 : aEvent.xclient.data.l[2] = 0;
1769 0 : aEvent.xclient.data.l[3] = 0;
1770 0 : aEvent.xclient.data.l[4] = 0;
1771 : XSendEvent( m_pDisplay,
1772 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
1773 : False,
1774 : SubstructureNotifyMask | SubstructureRedirectMask,
1775 : &aEvent
1776 0 : );
1777 : }
1778 : else
1779 : {
1780 0 : sal_uInt32 nNewLayer = bEnable ? 6 : 4;
1781 : XChangeProperty( m_pDisplay,
1782 : pFrame->GetShellWindow(),
1783 0 : m_aWMAtoms[ WIN_LAYER ],
1784 : XA_CARDINAL,
1785 : 32,
1786 : PropModeReplace,
1787 : (unsigned char*)&nNewLayer,
1788 : 1
1789 0 : );
1790 : }
1791 : }
1792 0 : }
1793 :
1794 : /*
1795 : * WMAdaptor::changeReferenceFrame
1796 : */
1797 0 : void WMAdaptor::changeReferenceFrame( X11SalFrame* pFrame, X11SalFrame* pReferenceFrame ) const
1798 : {
1799 0 : if( ! ( pFrame->nStyle_ & SAL_FRAME_STYLE_PLUG )
1800 0 : && ! pFrame->IsOverrideRedirect()
1801 0 : && ! pFrame->IsFloatGrabWindow()
1802 : )
1803 : {
1804 0 : XLIB_Window aTransient = pFrame->pDisplay_->GetRootWindow( pFrame->GetScreenNumber() );
1805 0 : pFrame->mbTransientForRoot = true;
1806 0 : if( pReferenceFrame )
1807 : {
1808 0 : aTransient = pReferenceFrame->GetShellWindow();
1809 0 : pFrame->mbTransientForRoot = false;
1810 : }
1811 : XSetTransientForHint( m_pDisplay,
1812 : pFrame->GetShellWindow(),
1813 0 : aTransient );
1814 : }
1815 0 : }
1816 :
1817 : /*
1818 : * WMAdaptor::handlePropertyNotify
1819 : */
1820 0 : int WMAdaptor::handlePropertyNotify( X11SalFrame*, XPropertyEvent* ) const
1821 : {
1822 0 : return 0;
1823 : }
1824 :
1825 : /*
1826 : * NetWMAdaptor::handlePropertyNotify
1827 : */
1828 0 : int NetWMAdaptor::handlePropertyNotify( X11SalFrame* pFrame, XPropertyEvent* pEvent ) const
1829 : {
1830 0 : int nHandled = 1;
1831 0 : if( pEvent->atom == m_aWMAtoms[ NET_WM_STATE ] )
1832 : {
1833 0 : pFrame->mbMaximizedHorz = pFrame->mbMaximizedVert = false;
1834 0 : pFrame->mbShaded = false;
1835 :
1836 0 : if( pEvent->state == PropertyNewValue )
1837 : {
1838 : Atom nType, *pStates;
1839 : int nFormat;
1840 : unsigned long nItems, nBytesLeft;
1841 0 : unsigned char* pData = NULL;
1842 0 : long nOffset = 0;
1843 0 : do
1844 : {
1845 : XGetWindowProperty( m_pDisplay,
1846 : pEvent->window,
1847 0 : m_aWMAtoms[ NET_WM_STATE ],
1848 : nOffset, 64,
1849 : False,
1850 : XA_ATOM,
1851 : &nType,
1852 : &nFormat,
1853 : &nItems, &nBytesLeft,
1854 0 : &pData );
1855 0 : if( pData )
1856 : {
1857 0 : if( nType == XA_ATOM && nFormat == 32 && nItems > 0 )
1858 : {
1859 0 : pStates = (Atom*)pData;
1860 0 : for( unsigned long i = 0; i < nItems; i++ )
1861 : {
1862 0 : if( pStates[i] == m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] )
1863 0 : pFrame->mbMaximizedVert = true;
1864 0 : else if( pStates[i] == m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ] && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ] )
1865 0 : pFrame->mbMaximizedHorz = true;
1866 0 : else if( pStates[i] == m_aWMAtoms[ NET_WM_STATE_SHADED ] && m_aWMAtoms[ NET_WM_STATE_SHADED ] )
1867 0 : pFrame->mbShaded = true;
1868 : }
1869 : }
1870 0 : XFree( pData );
1871 0 : pData = NULL;
1872 0 : nOffset += nItems * nFormat / 32;
1873 : }
1874 : else
1875 0 : break;
1876 0 : } while( nBytesLeft > 0 );
1877 : }
1878 :
1879 0 : if( ! (pFrame->mbMaximizedHorz || pFrame->mbMaximizedVert ) )
1880 0 : pFrame->maRestorePosSize = Rectangle();
1881 : else
1882 : {
1883 0 : const SalFrameGeometry& rGeom = pFrame->GetUnmirroredGeometry();
1884 : // the current geometry may already be changed by the corresponding
1885 : // ConfigureNotify, but this cannot be helped
1886 : pFrame->maRestorePosSize =
1887 : Rectangle( Point( rGeom.nX, rGeom.nY ),
1888 0 : Size( rGeom.nWidth, rGeom.nHeight ) );
1889 : }
1890 : }
1891 0 : else if( pEvent->atom == m_aWMAtoms[ NET_WM_DESKTOP ] )
1892 : {
1893 0 : pFrame->m_nWorkArea = getWindowWorkArea( pFrame->GetShellWindow() );
1894 : }
1895 : else
1896 0 : nHandled = 0;
1897 :
1898 0 : return nHandled;
1899 : }
1900 :
1901 : /*
1902 : * GnomeWMAdaptor::handlePropertyNotify
1903 : */
1904 0 : int GnomeWMAdaptor::handlePropertyNotify( X11SalFrame* pFrame, XPropertyEvent* pEvent ) const
1905 : {
1906 0 : int nHandled = 1;
1907 0 : if( pEvent->atom == m_aWMAtoms[ WIN_STATE ] )
1908 : {
1909 0 : pFrame->mbMaximizedHorz = pFrame->mbMaximizedVert = false;
1910 0 : pFrame->mbShaded = false;
1911 :
1912 0 : if( pEvent->state == PropertyNewValue )
1913 : {
1914 : Atom nType;
1915 0 : int nFormat = 0;
1916 0 : unsigned long nItems = 0;
1917 0 : unsigned long nBytesLeft = 0;
1918 0 : unsigned char* pData = 0;
1919 : XGetWindowProperty( m_pDisplay,
1920 : pEvent->window,
1921 0 : m_aWMAtoms[ WIN_STATE ],
1922 : 0, 1,
1923 : False,
1924 : XA_CARDINAL,
1925 : &nType,
1926 : &nFormat,
1927 : &nItems, &nBytesLeft,
1928 0 : &pData );
1929 0 : if( pData )
1930 : {
1931 0 : if( nType == XA_CARDINAL && nFormat == 32 && nItems == 1 )
1932 : {
1933 0 : sal_uInt32 nWinState = *(sal_uInt32*)pData;
1934 0 : if( nWinState & (1<<2) )
1935 0 : pFrame->mbMaximizedVert = true;
1936 0 : if( nWinState & (1<<3) )
1937 0 : pFrame->mbMaximizedHorz = true;
1938 0 : if( nWinState & (1<<5) )
1939 0 : pFrame->mbShaded = true;
1940 : }
1941 0 : XFree( pData );
1942 : }
1943 : }
1944 :
1945 0 : if( ! (pFrame->mbMaximizedHorz || pFrame->mbMaximizedVert ) )
1946 0 : pFrame->maRestorePosSize = Rectangle();
1947 : else
1948 : {
1949 0 : const SalFrameGeometry& rGeom = pFrame->GetUnmirroredGeometry();
1950 : // the current geometry may already be changed by the corresponding
1951 : // ConfigureNotify, but this cannot be helped
1952 : pFrame->maRestorePosSize =
1953 : Rectangle( Point( rGeom.nX, rGeom.nY ),
1954 0 : Size( rGeom.nWidth, rGeom.nHeight ) );
1955 : }
1956 : }
1957 0 : else if( pEvent->atom == m_aWMAtoms[ NET_WM_DESKTOP ] )
1958 : {
1959 0 : pFrame->m_nWorkArea = getWindowWorkArea( pFrame->GetShellWindow() );
1960 : }
1961 : else
1962 0 : nHandled = 0;
1963 :
1964 0 : return nHandled;
1965 : }
1966 :
1967 : /*
1968 : * WMAdaptor::shade
1969 : */
1970 0 : void WMAdaptor::shade( X11SalFrame*, bool /*bToShaded*/ ) const
1971 : {
1972 0 : }
1973 :
1974 : /*
1975 : * NetWMAdaptor::shade
1976 : */
1977 0 : void NetWMAdaptor::shade( X11SalFrame* pFrame, bool bToShaded ) const
1978 : {
1979 0 : if( m_aWMAtoms[ NET_WM_STATE ]
1980 0 : && m_aWMAtoms[ NET_WM_STATE_SHADED ]
1981 0 : && ( pFrame->nStyle_ & ~SAL_FRAME_STYLE_DEFAULT )
1982 : )
1983 : {
1984 0 : pFrame->mbShaded = bToShaded;
1985 0 : if( pFrame->bMapped_ )
1986 : {
1987 : // window already mapped, send WM a message
1988 : XEvent aEvent;
1989 0 : aEvent.type = ClientMessage;
1990 0 : aEvent.xclient.display = m_pDisplay;
1991 0 : aEvent.xclient.window = pFrame->GetShellWindow();
1992 0 : aEvent.xclient.message_type = m_aWMAtoms[ NET_WM_STATE ];
1993 0 : aEvent.xclient.format = 32;
1994 0 : aEvent.xclient.data.l[0] = bToShaded ? 1 : 0;
1995 0 : aEvent.xclient.data.l[1] = m_aWMAtoms[ NET_WM_STATE_SHADED ];
1996 0 : aEvent.xclient.data.l[2] = 0;
1997 0 : aEvent.xclient.data.l[3] = 0;
1998 0 : aEvent.xclient.data.l[4] = 0;
1999 : XSendEvent( m_pDisplay,
2000 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
2001 : False,
2002 : SubstructureNotifyMask | SubstructureRedirectMask,
2003 : &aEvent
2004 0 : );
2005 : }
2006 : else
2007 : {
2008 : // window not mapped yet, set _NET_WM_STATE directly
2009 0 : setNetWMState( pFrame );
2010 : }
2011 : }
2012 0 : }
2013 :
2014 : /*
2015 : * GnomeWMAdaptor::shade
2016 : */
2017 0 : void GnomeWMAdaptor::shade( X11SalFrame* pFrame, bool bToShaded ) const
2018 : {
2019 0 : if( m_aWMAtoms[ WIN_STATE ] )
2020 : {
2021 0 : pFrame->mbShaded = bToShaded;
2022 0 : if( pFrame->bMapped_ )
2023 : {
2024 : // window already mapped, send WM a message
2025 : XEvent aEvent;
2026 0 : aEvent.type = ClientMessage;
2027 0 : aEvent.xclient.display = m_pDisplay;
2028 0 : aEvent.xclient.window = pFrame->GetShellWindow();
2029 0 : aEvent.xclient.message_type = m_aWMAtoms[ WIN_STATE ];
2030 0 : aEvent.xclient.format = 32;
2031 0 : aEvent.xclient.data.l[0] = (1<<5);
2032 0 : aEvent.xclient.data.l[1] = bToShaded ? (1<<5) : 0;
2033 0 : aEvent.xclient.data.l[2] = 0;
2034 0 : aEvent.xclient.data.l[3] = 0;
2035 0 : aEvent.xclient.data.l[4] = 0;
2036 : XSendEvent( m_pDisplay,
2037 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
2038 : False,
2039 : SubstructureNotifyMask | SubstructureRedirectMask,
2040 : &aEvent
2041 0 : );
2042 : }
2043 : else
2044 0 : setGnomeWMState( pFrame );
2045 : }
2046 0 : }
2047 :
2048 : /*
2049 : * WMAdaptor::showFullScreen
2050 : */
2051 0 : void WMAdaptor::showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const
2052 : {
2053 0 : pFrame->mbFullScreen = bFullScreen;
2054 0 : maximizeFrame( pFrame, bFullScreen, bFullScreen );
2055 0 : }
2056 :
2057 : /*
2058 : * NetWMAdaptor::showFullScreen
2059 : */
2060 0 : void NetWMAdaptor::showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const
2061 : {
2062 0 : if( m_aWMAtoms[ NET_WM_STATE_FULLSCREEN ] )
2063 : {
2064 0 : pFrame->mbFullScreen = bFullScreen;
2065 0 : if( bFullScreen )
2066 : {
2067 0 : if( m_aWMAtoms[ MOTIF_WM_HINTS ] )
2068 : {
2069 : XDeleteProperty( m_pDisplay,
2070 : pFrame->GetShellWindow(),
2071 0 : m_aWMAtoms[ MOTIF_WM_HINTS ] );
2072 : }
2073 : }
2074 0 : if( pFrame->bMapped_ )
2075 : {
2076 : // window already mapped, send WM a message
2077 : XEvent aEvent;
2078 0 : aEvent.type = ClientMessage;
2079 0 : aEvent.xclient.display = m_pDisplay;
2080 0 : aEvent.xclient.window = pFrame->GetShellWindow();
2081 0 : aEvent.xclient.message_type = m_aWMAtoms[ NET_WM_STATE ];
2082 0 : aEvent.xclient.format = 32;
2083 0 : aEvent.xclient.data.l[0] = bFullScreen ? 1 : 0;
2084 0 : aEvent.xclient.data.l[1] = m_aWMAtoms[ NET_WM_STATE_FULLSCREEN ];
2085 0 : aEvent.xclient.data.l[2] = 0;
2086 0 : aEvent.xclient.data.l[3] = 0;
2087 0 : aEvent.xclient.data.l[4] = 0;
2088 : XSendEvent( m_pDisplay,
2089 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
2090 : False,
2091 : SubstructureNotifyMask | SubstructureRedirectMask,
2092 : &aEvent
2093 0 : );
2094 : }
2095 : else
2096 : {
2097 : // window not mapped yet, set _NET_WM_STATE directly
2098 0 : setNetWMState( pFrame );
2099 : }
2100 : // #i42750# guess size before resize event shows up
2101 0 : if( bFullScreen )
2102 : {
2103 0 : if( m_pSalDisplay->IsXinerama() )
2104 : {
2105 : XLIB_Window aRoot, aChild;
2106 0 : int root_x = 0, root_y = 0, lx, ly;
2107 : unsigned int mask;
2108 : XQueryPointer( m_pDisplay,
2109 : m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
2110 : &aRoot, &aChild,
2111 0 : &root_x, &root_y, &lx, &ly, &mask );
2112 0 : const std::vector< Rectangle >& rScreens = m_pSalDisplay->GetXineramaScreens();
2113 0 : Point aMousePoint( root_x, root_y );
2114 0 : for( unsigned int i = 0; i < rScreens.size(); i++ )
2115 : {
2116 0 : if( rScreens[i].IsInside( aMousePoint ) )
2117 : {
2118 0 : pFrame->maGeometry.nX = rScreens[i].Left();
2119 0 : pFrame->maGeometry.nY = rScreens[i].Top();
2120 0 : pFrame->maGeometry.nWidth = rScreens[i].GetWidth();
2121 0 : pFrame->maGeometry.nHeight = rScreens[i].GetHeight();
2122 0 : break;
2123 : }
2124 : }
2125 : }
2126 : else
2127 : {
2128 0 : Size aSize = m_pSalDisplay->GetScreenSize( pFrame->GetScreenNumber() );
2129 0 : pFrame->maGeometry.nX = 0;
2130 0 : pFrame->maGeometry.nY = 0;
2131 0 : pFrame->maGeometry.nWidth = aSize.Width();
2132 0 : pFrame->maGeometry.nHeight = aSize.Height();
2133 : }
2134 0 : pFrame->CallCallback( SALEVENT_MOVERESIZE, NULL );
2135 : }
2136 : }
2137 0 : else WMAdaptor::showFullScreen( pFrame, bFullScreen );
2138 0 : }
2139 :
2140 : /*
2141 : * WMAdaptor::getCurrentWorkArea
2142 : */
2143 : // FIXME: multiscreen case
2144 0 : int WMAdaptor::getCurrentWorkArea() const
2145 : {
2146 0 : int nCurrent = -1;
2147 0 : if( m_aWMAtoms[ NET_CURRENT_DESKTOP ] )
2148 : {
2149 0 : Atom aRealType = None;
2150 0 : int nFormat = 8;
2151 0 : unsigned long nItems = 0;
2152 0 : unsigned long nBytesLeft = 0;
2153 0 : unsigned char* pProperty = NULL;
2154 0 : if( XGetWindowProperty( m_pDisplay,
2155 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
2156 0 : m_aWMAtoms[ NET_CURRENT_DESKTOP ],
2157 : 0, 1,
2158 : False,
2159 : XA_CARDINAL,
2160 : &aRealType,
2161 : &nFormat,
2162 : &nItems,
2163 : &nBytesLeft,
2164 0 : &pProperty ) == 0
2165 0 : && pProperty
2166 : )
2167 : {
2168 0 : nCurrent = int(*(sal_Int32*)pProperty);
2169 0 : XFree( pProperty );
2170 : }
2171 0 : else if( pProperty )
2172 : {
2173 0 : XFree( pProperty );
2174 0 : pProperty = NULL;
2175 : }
2176 : }
2177 0 : return nCurrent;
2178 : }
2179 :
2180 : /*
2181 : * WMAdaptor::getWindowWorkArea
2182 : */
2183 0 : int WMAdaptor::getWindowWorkArea( XLIB_Window aWindow ) const
2184 : {
2185 0 : int nCurrent = -1;
2186 0 : if( m_aWMAtoms[ NET_WM_DESKTOP ] )
2187 : {
2188 0 : Atom aRealType = None;
2189 0 : int nFormat = 8;
2190 0 : unsigned long nItems = 0;
2191 0 : unsigned long nBytesLeft = 0;
2192 0 : unsigned char* pProperty = NULL;
2193 0 : if( XGetWindowProperty( m_pDisplay,
2194 : aWindow,
2195 0 : m_aWMAtoms[ NET_WM_DESKTOP ],
2196 : 0, 1,
2197 : False,
2198 : XA_CARDINAL,
2199 : &aRealType,
2200 : &nFormat,
2201 : &nItems,
2202 : &nBytesLeft,
2203 0 : &pProperty ) == 0
2204 0 : && pProperty
2205 : )
2206 : {
2207 0 : nCurrent = int(*(sal_Int32*)pProperty);
2208 0 : XFree( pProperty );
2209 : }
2210 0 : else if( pProperty )
2211 : {
2212 0 : XFree( pProperty );
2213 0 : pProperty = NULL;
2214 : }
2215 : }
2216 0 : return nCurrent;
2217 : }
2218 :
2219 : /*
2220 : * WMAdaptor::getCurrentWorkArea
2221 : */
2222 : // fixme: multi screen case
2223 0 : void WMAdaptor::switchToWorkArea( int nWorkArea, bool bConsiderWM ) const
2224 : {
2225 0 : if( bConsiderWM && ! getWMshouldSwitchWorkspace() )
2226 0 : return;
2227 :
2228 0 : if( m_aWMAtoms[ NET_CURRENT_DESKTOP ] )
2229 : {
2230 : XEvent aEvent;
2231 0 : aEvent.type = ClientMessage;
2232 0 : aEvent.xclient.display = m_pDisplay;
2233 0 : aEvent.xclient.window = m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() );
2234 0 : aEvent.xclient.message_type = m_aWMAtoms[ NET_CURRENT_DESKTOP ];
2235 0 : aEvent.xclient.format = 32;
2236 0 : aEvent.xclient.data.l[0] = nWorkArea;
2237 0 : aEvent.xclient.data.l[1] = 0;
2238 0 : aEvent.xclient.data.l[2] = 0;
2239 0 : aEvent.xclient.data.l[3] = 0;
2240 0 : aEvent.xclient.data.l[4] = 0;
2241 : XSendEvent( m_pDisplay,
2242 : m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
2243 : False,
2244 : SubstructureNotifyMask | SubstructureRedirectMask,
2245 : &aEvent
2246 0 : );
2247 : }
2248 : }
2249 :
2250 : /*
2251 : * WMAdaptor::frameIsMapping
2252 : */
2253 0 : void WMAdaptor::frameIsMapping( X11SalFrame* ) const
2254 : {
2255 0 : }
2256 :
2257 : /*
2258 : * NetWMAdaptor::frameIsMapping
2259 : */
2260 0 : void NetWMAdaptor::frameIsMapping( X11SalFrame* pFrame ) const
2261 : {
2262 0 : setNetWMState( pFrame );
2263 0 : }
2264 :
2265 : /*
2266 : * WMAdaptor::setFrameStruts
2267 : */
2268 0 : void WMAdaptor::setFrameStruts( X11SalFrame*,
2269 : int, int, int, int,
2270 : int, int, int, int,
2271 : int, int, int, int ) const
2272 : {
2273 0 : }
2274 :
2275 : /*
2276 : * NetWMAdaptor::setFrameStruts
2277 : */
2278 0 : void NetWMAdaptor::setFrameStruts( X11SalFrame* pFrame,
2279 : int left, int right, int top, int bottom,
2280 : int left_start_y, int left_end_y,
2281 : int right_start_y, int right_end_y,
2282 : int top_start_x, int top_end_x,
2283 : int bottom_start_x, int bottom_end_x ) const
2284 : {
2285 : long nData[12];
2286 0 : nData[0] = left;
2287 0 : nData[1] = right;
2288 0 : nData[2] = top;
2289 0 : nData[3] = bottom;
2290 0 : nData[4] = left_start_y;
2291 0 : nData[5] = left_end_y;
2292 0 : nData[6] = right_start_y;
2293 0 : nData[7] = right_end_y;
2294 0 : nData[8] = top_start_x;
2295 0 : nData[9] = top_end_x;
2296 0 : nData[10]= bottom_start_x;
2297 0 : nData[11]= bottom_end_x;
2298 0 : Atom aProperty = None;
2299 0 : int nSetData = 0;
2300 :
2301 0 : if( m_aWMAtoms[NET_WM_STRUT_PARTIAL] )
2302 : {
2303 0 : aProperty = m_aWMAtoms[NET_WM_STRUT_PARTIAL];
2304 0 : nSetData = 12;
2305 : }
2306 0 : else if( m_aWMAtoms[NET_WM_STRUT] )
2307 : {
2308 0 : aProperty = m_aWMAtoms[NET_WM_STRUT];
2309 0 : nSetData = 4;
2310 : }
2311 0 : if( nSetData )
2312 : {
2313 : XChangeProperty( m_pDisplay,
2314 : pFrame->GetShellWindow(),
2315 : aProperty,
2316 : XA_CARDINAL,
2317 : 32,
2318 : PropModeReplace,
2319 : (unsigned char*)&nData,
2320 : nSetData
2321 0 : );
2322 : }
2323 0 : }
2324 :
2325 : /*
2326 : * WMAdaptor::setUserTime
2327 : */
2328 0 : void WMAdaptor::setUserTime( X11SalFrame*, long ) const
2329 : {
2330 0 : }
2331 :
2332 : /*
2333 : * NetWMAdaptor::setUserTime
2334 : */
2335 0 : void NetWMAdaptor::setUserTime( X11SalFrame* i_pFrame, long i_nUserTime ) const
2336 : {
2337 0 : if( m_aWMAtoms[NET_WM_USER_TIME] )
2338 : {
2339 : XChangeProperty( m_pDisplay,
2340 : i_pFrame->GetShellWindow(),
2341 0 : m_aWMAtoms[NET_WM_USER_TIME],
2342 : XA_CARDINAL,
2343 : 32,
2344 : PropModeReplace,
2345 : (unsigned char*)&i_nUserTime,
2346 : 1
2347 0 : );
2348 : }
2349 0 : }
2350 :
2351 : /*
2352 : * WMAdaptor::setPID
2353 : */
2354 0 : void WMAdaptor::setPID( X11SalFrame* i_pFrame ) const
2355 : {
2356 0 : if( m_aWMAtoms[NET_WM_PID] )
2357 : {
2358 0 : long nPID = (long)getpid();
2359 : XChangeProperty( m_pDisplay,
2360 : i_pFrame->GetShellWindow(),
2361 0 : m_aWMAtoms[NET_WM_PID],
2362 : XA_CARDINAL,
2363 : 32,
2364 : PropModeReplace,
2365 : (unsigned char*)&nPID,
2366 : 1
2367 0 : );
2368 : }
2369 0 : }
2370 :
2371 : /*
2372 : * WMAdaptor::setClientMachine
2373 : */
2374 0 : void WMAdaptor::setClientMachine( X11SalFrame* i_pFrame ) const
2375 : {
2376 0 : OString aWmClient( OUStringToOString( GetGenericData()->GetHostname(), RTL_TEXTENCODING_ASCII_US ) );
2377 0 : XTextProperty aClientProp = { (unsigned char*)aWmClient.getStr(), XA_STRING, 8, sal::static_int_cast<unsigned long>( aWmClient.getLength() ) };
2378 0 : XSetWMClientMachine( m_pDisplay, i_pFrame->GetShellWindow(), &aClientProp );
2379 0 : }
2380 :
2381 0 : void WMAdaptor::answerPing( X11SalFrame* i_pFrame, XClientMessageEvent* i_pEvent ) const
2382 : {
2383 0 : if( m_aWMAtoms[NET_WM_PING] &&
2384 0 : i_pEvent->message_type == m_aWMAtoms[ WM_PROTOCOLS ] &&
2385 0 : (Atom)i_pEvent->data.l[0] == m_aWMAtoms[ NET_WM_PING ] )
2386 : {
2387 : XEvent aEvent;
2388 0 : aEvent.xclient = *i_pEvent;
2389 0 : aEvent.xclient.window = m_pSalDisplay->GetRootWindow( i_pFrame->GetScreenNumber() );
2390 : XSendEvent( m_pDisplay,
2391 : m_pSalDisplay->GetRootWindow( i_pFrame->GetScreenNumber() ),
2392 : False,
2393 : SubstructureNotifyMask | SubstructureRedirectMask,
2394 : &aEvent
2395 0 : );
2396 0 : XFlush( m_pDisplay );
2397 : }
2398 0 : }
2399 :
2400 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|