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