1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
23 #include <i18nlangtag/languagetag.hxx>
24 #include <rtl/locale.h>
26 #include <osl/thread.h>
27 #include <osl/process.h>
28 #include <sal/macros.h>
29 #include <sal/log.hxx>
30 #include <configsettings.hxx>
32 #include <unx/wmadaptor.hxx>
33 #include <unx/saldisp.hxx>
34 #include <unx/salframe.h>
37 #include <X11/Xutil.h>
38 #include <X11/Xatom.h>
42 class NetWMAdaptor
: public WMAdaptor
44 void setNetWMState( X11SalFrame
* pFrame
) const;
46 virtual bool isValid() const override
;
48 explicit NetWMAdaptor( SalDisplay
* );
50 virtual void setWMName( X11SalFrame
* pFrame
, const OUString
& rWMName
) const override
;
51 virtual void maximizeFrame( X11SalFrame
* pFrame
, bool bHorizontal
= true, bool bVertical
= true ) const override
;
52 virtual void shade( X11SalFrame
* pFrame
, bool bToShaded
) const override
;
53 virtual void setFrameTypeAndDecoration( X11SalFrame
* pFrame
, WMWindowType eType
, int nDecorationFlags
, X11SalFrame
* pTransientFrame
) const override
;
54 virtual void enableAlwaysOnTop( X11SalFrame
* pFrame
, bool bEnable
) const override
;
55 virtual int handlePropertyNotify( X11SalFrame
* pFrame
, XPropertyEvent
* pEvent
) const override
;
56 virtual void showFullScreen( X11SalFrame
* pFrame
, bool bFullScreen
) const override
;
57 virtual void frameIsMapping( X11SalFrame
* pFrame
) const override
;
58 virtual void setUserTime( X11SalFrame
* i_pFrame
, tools::Long i_nUserTime
) const override
;
61 class GnomeWMAdaptor
: public WMAdaptor
65 void setGnomeWMState( X11SalFrame
* pFrame
) const;
67 virtual bool isValid() const override
;
69 explicit GnomeWMAdaptor( SalDisplay
* );
71 virtual void maximizeFrame( X11SalFrame
* pFrame
, bool bHorizontal
= true, bool bVertical
= true ) const override
;
72 virtual void shade( X11SalFrame
* pFrame
, bool bToShaded
) const override
;
73 virtual void enableAlwaysOnTop( X11SalFrame
* pFrame
, bool bEnable
) const override
;
74 virtual int handlePropertyNotify( X11SalFrame
* pFrame
, XPropertyEvent
* pEvent
) const override
;
79 using namespace vcl_sal
;
83 struct WMAdaptorProtocol
85 const char* pProtocol
;
92 * table must be sorted ascending in strings
93 * since it is use with bsearch
95 const WMAdaptorProtocol aProtocolTab
[] =
97 { "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", WMAdaptor::KDE_NET_WM_WINDOW_TYPE_OVERRIDE
},
98 { "_NET_ACTIVE_WINDOW", WMAdaptor::NET_ACTIVE_WINDOW
},
99 { "_NET_CURRENT_DESKTOP", WMAdaptor::NET_CURRENT_DESKTOP
},
100 { "_NET_NUMBER_OF_DESKTOPS", WMAdaptor::NET_NUMBER_OF_DESKTOPS
},
101 { "_NET_WM_DESKTOP", WMAdaptor::NET_WM_DESKTOP
},
102 { "_NET_WM_ICON", WMAdaptor::NET_WM_ICON
},
103 { "_NET_WM_ICON_NAME", WMAdaptor::NET_WM_ICON_NAME
},
104 { "_NET_WM_PING", WMAdaptor::NET_WM_PING
},
105 { "_NET_WM_STATE", WMAdaptor::NET_WM_STATE
},
106 { "_NET_WM_STATE_ABOVE", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP
},
107 { "_NET_WM_STATE_FULLSCREEN", WMAdaptor::NET_WM_STATE_FULLSCREEN
},
108 { "_NET_WM_STATE_MAXIMIZED_HORIZ", WMAdaptor::NET_WM_STATE_MAXIMIZED_HORZ
}, // common bug in e.g. older kwin and sawfish implementations
109 { "_NET_WM_STATE_MAXIMIZED_HORZ", WMAdaptor::NET_WM_STATE_MAXIMIZED_HORZ
},
110 { "_NET_WM_STATE_MAXIMIZED_VERT", WMAdaptor::NET_WM_STATE_MAXIMIZED_VERT
},
111 { "_NET_WM_STATE_MODAL", WMAdaptor::NET_WM_STATE_MODAL
},
112 { "_NET_WM_STATE_SHADED", WMAdaptor::NET_WM_STATE_SHADED
},
113 { "_NET_WM_STATE_SKIP_PAGER", WMAdaptor::NET_WM_STATE_SKIP_PAGER
},
114 { "_NET_WM_STATE_SKIP_TASKBAR", WMAdaptor::NET_WM_STATE_SKIP_TASKBAR
},
115 { "_NET_WM_STATE_STAYS_ON_TOP", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP
},
116 { "_NET_WM_STATE_STICKY", WMAdaptor::NET_WM_STATE_STICKY
},
117 { "_NET_WM_STRUT", WMAdaptor::NET_WM_STRUT
},
118 { "_NET_WM_STRUT_PARTIAL", WMAdaptor::NET_WM_STRUT_PARTIAL
},
119 { "_NET_WM_WINDOW_TYPE", WMAdaptor::NET_WM_WINDOW_TYPE
},
120 { "_NET_WM_WINDOW_TYPE_DESKTOP", WMAdaptor::NET_WM_WINDOW_TYPE_DESKTOP
},
121 { "_NET_WM_WINDOW_TYPE_DIALOG", WMAdaptor::NET_WM_WINDOW_TYPE_DIALOG
},
122 { "_NET_WM_WINDOW_TYPE_DOCK", WMAdaptor::NET_WM_WINDOW_TYPE_DOCK
},
123 { "_NET_WM_WINDOW_TYPE_MENU", WMAdaptor::NET_WM_WINDOW_TYPE_MENU
},
124 { "_NET_WM_WINDOW_TYPE_NORMAL", WMAdaptor::NET_WM_WINDOW_TYPE_NORMAL
},
125 { "_NET_WM_WINDOW_TYPE_SPLASH", WMAdaptor::NET_WM_WINDOW_TYPE_SPLASH
},
126 { "_NET_WM_WINDOW_TYPE_SPLASHSCREEN", WMAdaptor::NET_WM_WINDOW_TYPE_SPLASH
}, // bug in Metacity 2.4.1
127 { "_NET_WM_WINDOW_TYPE_TOOLBAR", WMAdaptor::NET_WM_WINDOW_TYPE_TOOLBAR
},
128 { "_NET_WM_WINDOW_TYPE_UTILITY", WMAdaptor::NET_WM_WINDOW_TYPE_UTILITY
},
129 { "_NET_WORKAREA", WMAdaptor::NET_WORKAREA
},
130 { "_WIN_APP_STATE", WMAdaptor::WIN_APP_STATE
},
131 { "_WIN_CLIENT_LIST", WMAdaptor::WIN_CLIENT_LIST
},
132 { "_WIN_EXPANDED_SIZE", WMAdaptor::WIN_EXPANDED_SIZE
},
133 { "_WIN_HINTS", WMAdaptor::WIN_HINTS
},
134 { "_WIN_ICONS", WMAdaptor::WIN_ICONS
},
135 { "_WIN_LAYER", WMAdaptor::WIN_LAYER
},
136 { "_WIN_STATE", WMAdaptor::WIN_STATE
},
137 { "_WIN_WORKSPACE", WMAdaptor::WIN_WORKSPACE
},
138 { "_WIN_WORKSPACE_COUNT", WMAdaptor::WIN_WORKSPACE_COUNT
}
142 * table containing atoms to get anyway
145 const WMAdaptorProtocol aAtomTab
[] =
147 { "WM_STATE", WMAdaptor::WM_STATE
},
148 { "_MOTIF_WM_HINTS", WMAdaptor::MOTIF_WM_HINTS
},
149 { "WM_PROTOCOLS", WMAdaptor::WM_PROTOCOLS
},
150 { "WM_DELETE_WINDOW", WMAdaptor::WM_DELETE_WINDOW
},
151 { "WM_TAKE_FOCUS", WMAdaptor::WM_TAKE_FOCUS
},
152 { "WM_COMMAND", WMAdaptor::WM_COMMAND
},
153 { "WM_CLIENT_LEADER", WMAdaptor::WM_CLIENT_LEADER
},
154 { "WM_LOCALE_NAME", WMAdaptor::WM_LOCALE_NAME
},
155 { "WM_TRANSIENT_FOR", WMAdaptor::WM_TRANSIENT_FOR
},
156 { "SAL_QUITEVENT", WMAdaptor::SAL_QUITEVENT
},
157 { "SAL_USEREVENT", WMAdaptor::SAL_USEREVENT
},
158 { "SAL_EXTTEXTEVENT", WMAdaptor::SAL_EXTTEXTEVENT
},
159 { "SAL_GETTIMEEVENT", WMAdaptor::SAL_GETTIMEEVENT
},
160 { "VCL_SYSTEM_SETTINGS", WMAdaptor::VCL_SYSTEM_SETTINGS
},
161 { "_XSETTINGS_SETTINGS", WMAdaptor::XSETTINGS
},
162 { "_XEMBED", WMAdaptor::XEMBED
},
163 { "_XEMBED_INFO", WMAdaptor::XEMBED_INFO
},
164 { "_NET_WM_USER_TIME", WMAdaptor::NET_WM_USER_TIME
},
165 { "_NET_WM_PID", WMAdaptor::NET_WM_PID
}
169 static int compareProtocol( const void* pLeft
, const void* pRight
)
171 return strcmp( static_cast<const WMAdaptorProtocol
*>(pLeft
)->pProtocol
, static_cast<const WMAdaptorProtocol
*>(pRight
)->pProtocol
);
175 std::unique_ptr
<WMAdaptor
> WMAdaptor::createWMAdaptor( SalDisplay
* pSalDisplay
)
177 std::unique_ptr
<WMAdaptor
> pAdaptor
;
180 pAdaptor
.reset(new NetWMAdaptor( pSalDisplay
));
181 if( ! pAdaptor
->isValid() )
185 #if OSL_DEBUG_LEVEL > 1
187 SAL_INFO("vcl.app", "WM supports extended WM hints.");
193 pAdaptor
.reset(new GnomeWMAdaptor( pSalDisplay
));
194 if( ! pAdaptor
->isValid() )
198 #if OSL_DEBUG_LEVEL > 1
200 SAL_INFO("vcl.app", "WM supports GNOME WM hints.");
205 pAdaptor
.reset(new WMAdaptor( pSalDisplay
));
207 #if OSL_DEBUG_LEVEL > 1
208 SAL_INFO("vcl.app", "Window Manager's name is \""
209 << pAdaptor
->getWindowManagerName()
216 * WMAdaptor constructor
219 WMAdaptor::WMAdaptor( SalDisplay
* pDisplay
) :
220 m_pSalDisplay( pDisplay
),
221 m_bEnableAlwaysOnTopWorks( false ),
222 m_bLegacyPartialFullscreen( false ),
223 m_nWinGravity( StaticGravity
),
224 m_nInitWinGravity( StaticGravity
),
225 m_bWMshouldSwitchWorkspace( true ),
226 m_bWMshouldSwitchWorkspaceInit( false )
228 Atom aRealType
= None
;
230 unsigned long nItems
= 0;
231 unsigned long nBytesLeft
= 0;
232 unsigned char* pProperty
= nullptr;
236 m_aWMWorkAreas
= ::std::vector
< tools::Rectangle
>
237 ( 1, tools::Rectangle( Point(), m_pSalDisplay
->GetScreenSize( m_pSalDisplay
->GetDefaultXScreen() ) ) );
238 m_bEqualWorkAreas
= true;
240 memset( m_aWMAtoms
, 0, sizeof( m_aWMAtoms
) );
241 m_pDisplay
= m_pSalDisplay
->GetDisplay();
244 getNetWmName(); // try to discover e.g. Sawfish
246 if( m_aWMName
.isEmpty() )
248 // check for ReflectionX wm (as it needs a workaround in Windows mode
249 Atom aRwmRunning
= XInternAtom( m_pDisplay
, "RWM_RUNNING", True
);
250 if( aRwmRunning
!= None
&&
251 XGetWindowProperty( m_pDisplay
,
252 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
263 if( aRealType
== aRwmRunning
)
264 m_aWMName
= "ReflectionX";
269 aRwmRunning
= XInternAtom( m_pDisplay
, "_WRQ_WM_RUNNING", True
);
270 if( aRwmRunning
!= None
&&
271 XGetWindowProperty( m_pDisplay
,
272 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
283 if( aRealType
== XA_STRING
)
284 m_aWMName
= "ReflectionX Windows";
289 if( !m_aWMName
.isEmpty() )
292 Atom aTTAPlatform
= XInternAtom( m_pDisplay
, "TTA_CLIENT_PLATFORM", True
);
293 if( aTTAPlatform
== None
||
294 XGetWindowProperty( m_pDisplay
,
295 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
307 if( aRealType
== XA_STRING
)
309 m_aWMName
= "Tarantella";
310 // #i62319# pretend that AlwaysOnTop works since
311 // the alwaysontop workaround in salframe.cxx results
312 // in a raise/lower loop on a Windows tarantella client
313 // FIXME: this property contains an identification string that
314 // in theory should be good enough to recognize running on a
315 // Windows client; however this string does not seem to be
316 // documented as well as the property itself.
317 m_bEnableAlwaysOnTopWorks
= true;
323 * WMAdaptor destructor
326 WMAdaptor::~WMAdaptor()
331 * NetWMAdaptor constructor
334 NetWMAdaptor::NetWMAdaptor( SalDisplay
* pSalDisplay
) :
335 WMAdaptor( pSalDisplay
)
337 // currently all _NET WMs do transient like expected
339 Atom aRealType
= None
;
341 unsigned long nItems
= 0;
342 unsigned long nBytesLeft
= 0;
343 unsigned char* pProperty
= nullptr;
348 bool bNetWM
= getNetWmName();
350 && XGetWindowProperty( m_pDisplay
,
351 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
352 m_aWMAtoms
[ NET_SUPPORTED
],
361 && aRealType
== XA_ATOM
370 // collect supported protocols
371 if( XGetWindowProperty( m_pDisplay
,
372 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
373 m_aWMAtoms
[ NET_SUPPORTED
],
385 Atom
* pAtoms
= reinterpret_cast<Atom
*>(pProperty
);
386 char** pAtomNames
= static_cast<char**>(alloca( sizeof(char*)*nItems
));
387 if( XGetAtomNames( m_pDisplay
, pAtoms
, nItems
, pAtomNames
) )
389 #if OSL_DEBUG_LEVEL > 1
390 SAL_INFO("vcl.app", "supported protocols:");
392 for( unsigned long i
= 0; i
< nItems
; i
++ )
394 // #i80971# protect against invalid atoms
395 if( pAtomNames
[i
] == nullptr )
398 WMAdaptorProtocol aSearch
;
399 aSearch
.pProtocol
= pAtomNames
[i
];
400 WMAdaptorProtocol
* pMatch
= static_cast<WMAdaptorProtocol
*>(
403 SAL_N_ELEMENTS( aProtocolTab
),
404 sizeof( struct WMAdaptorProtocol
),
408 m_aWMAtoms
[ pMatch
->nProtocol
] = pAtoms
[ i
];
409 if( pMatch
->nProtocol
== NET_WM_STATE_STAYS_ON_TOP
)
410 m_bEnableAlwaysOnTopWorks
= true;
412 #if OSL_DEBUG_LEVEL > 1
413 SAL_INFO("vcl.app", " "
415 << (((pMatch
)&&(pMatch
->nProtocol
!= -1)) ?
416 "" : " (unsupported)"));
418 XFree( pAtomNames
[i
] );
430 // get number of desktops
431 if( m_aWMAtoms
[ NET_NUMBER_OF_DESKTOPS
]
432 && XGetWindowProperty( m_pDisplay
,
433 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
434 m_aWMAtoms
[ NET_NUMBER_OF_DESKTOPS
],
446 m_nDesktops
= *reinterpret_cast<long*>(pProperty
);
450 if( m_aWMAtoms
[ NET_WORKAREA
]
451 && XGetWindowProperty( m_pDisplay
,
452 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
453 m_aWMAtoms
[ NET_WORKAREA
],
463 && nItems
== 4*static_cast<unsigned>(m_nDesktops
)
466 m_aWMWorkAreas
= ::std::vector
< tools::Rectangle
> ( m_nDesktops
);
467 tools::Long
* pValues
= reinterpret_cast<long*>(pProperty
);
468 for( int i
= 0; i
< m_nDesktops
; i
++ )
470 Point
aPoint( pValues
[4*i
],
472 Size
aSize( pValues
[4*i
+2],
474 tools::Rectangle
aWorkArea( aPoint
, aSize
);
475 m_aWMWorkAreas
[i
] = aWorkArea
;
476 if( aWorkArea
!= m_aWMWorkAreas
[0] )
477 m_bEqualWorkAreas
= false;
478 #if OSL_DEBUG_LEVEL > 1
479 SAL_INFO("vcl.app", "workarea " << i
480 << ": " << m_aWMWorkAreas
[i
].GetWidth()
481 << "x" << m_aWMWorkAreas
[i
].GetHeight()
482 << "+" << m_aWMWorkAreas
[i
].Left()
483 << "+" << m_aWMWorkAreas
[i
].Top());
490 #if OSL_DEBUG_LEVEL > 1
491 SAL_INFO("vcl.app", nItems
/4 << " workareas for "
492 << m_nDesktops
<< " desktops !");
515 * GnomeWMAdaptor constructor
518 GnomeWMAdaptor::GnomeWMAdaptor( SalDisplay
* pSalDisplay
) :
519 WMAdaptor( pSalDisplay
),
522 // currently all Gnome WMs do transient like expected
524 Atom aRealType
= None
;
526 unsigned long nItems
= 0;
527 unsigned long nBytesLeft
= 0;
528 unsigned char* pProperty
= nullptr;
533 if( m_aWMAtoms
[ WIN_SUPPORTING_WM_CHECK
] && m_aWMAtoms
[ WIN_PROTOCOLS
] )
535 if( XGetWindowProperty( m_pDisplay
,
536 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
537 m_aWMAtoms
[ WIN_SUPPORTING_WM_CHECK
],
546 && aRealType
== XA_CARDINAL
551 ::Window aWMChild
= *reinterpret_cast< ::Window
* >(pProperty
);
554 GetGenericUnixSalData()->ErrorTrapPush();
555 if( XGetWindowProperty( m_pDisplay
,
557 m_aWMAtoms
[ WIN_SUPPORTING_WM_CHECK
],
566 && aRealType
== XA_CARDINAL
570 if (! GetGenericUnixSalData()->ErrorTrapPop( false ) )
572 GetGenericUnixSalData()->ErrorTrapPush();
574 ::Window aCheckWindow
= *reinterpret_cast< ::Window
* >(pProperty
);
577 if( aCheckWindow
== aWMChild
)
582 * this is NOT part of the GNOME WM hints, but e.g. Sawfish
583 * already supports this part of the extended WM hints
585 m_aWMAtoms
[ UTF8_STRING
] = XInternAtom( m_pDisplay
, "UTF8_STRING", False
);
590 GetGenericUnixSalData()->ErrorTrapPush();
592 GetGenericUnixSalData()->ErrorTrapPop();
601 && XGetWindowProperty( m_pDisplay
,
602 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
603 m_aWMAtoms
[ WIN_PROTOCOLS
],
612 && aRealType
== XA_ATOM
621 // collect supported protocols
622 if( XGetWindowProperty( m_pDisplay
,
623 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
624 m_aWMAtoms
[ WIN_PROTOCOLS
],
636 Atom
* pAtoms
= reinterpret_cast<Atom
*>(pProperty
);
637 char** pAtomNames
= static_cast<char**>(alloca( sizeof(char*)*nItems
));
638 if( XGetAtomNames( m_pDisplay
, pAtoms
, nItems
, pAtomNames
) )
640 #if OSL_DEBUG_LEVEL > 1
641 SAL_INFO("vcl.app", "supported protocols:");
643 for( unsigned long i
= 0; i
< nItems
; i
++ )
645 // #i80971# protect against invalid atoms
646 if( pAtomNames
[i
] == nullptr )
649 WMAdaptorProtocol aSearch
;
650 aSearch
.pProtocol
= pAtomNames
[i
];
651 WMAdaptorProtocol
* pMatch
= static_cast<WMAdaptorProtocol
*>(
654 SAL_N_ELEMENTS( aProtocolTab
),
655 sizeof( struct WMAdaptorProtocol
),
659 m_aWMAtoms
[ pMatch
->nProtocol
] = pAtoms
[ i
];
660 if( pMatch
->nProtocol
== WIN_LAYER
)
661 m_bEnableAlwaysOnTopWorks
= true;
663 if( strncmp( "_ICEWM_TRAY", pAtomNames
[i
], 11 ) == 0 )
666 m_nWinGravity
= NorthWestGravity
;
667 m_nInitWinGravity
= NorthWestGravity
;
669 #if OSL_DEBUG_LEVEL > 1
670 SAL_INFO("vcl.app", " "
672 << (((pMatch
) && (pMatch
->nProtocol
!= -1)) ?
673 "" : " (unsupported)"));
675 XFree( pAtomNames
[i
] );
687 // get number of desktops
688 if( m_aWMAtoms
[ WIN_WORKSPACE_COUNT
]
689 && XGetWindowProperty( m_pDisplay
,
690 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
691 m_aWMAtoms
[ WIN_WORKSPACE_COUNT
],
703 m_nDesktops
= *reinterpret_cast<long*>(pProperty
);
723 bool WMAdaptor::getNetWmName()
725 Atom aRealType
= None
;
727 unsigned long nItems
= 0;
728 unsigned long nBytesLeft
= 0;
729 unsigned char* pProperty
= nullptr;
732 if( m_aWMAtoms
[ NET_SUPPORTING_WM_CHECK
] && m_aWMAtoms
[ NET_WM_NAME
] )
734 if( XGetWindowProperty( m_pDisplay
,
735 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
736 m_aWMAtoms
[ NET_SUPPORTING_WM_CHECK
],
745 && aRealType
== XA_WINDOW
750 ::Window aWMChild
= *reinterpret_cast< ::Window
* >(pProperty
);
753 GetGenericUnixSalData()->ErrorTrapPush();
754 if( XGetWindowProperty( m_pDisplay
,
756 m_aWMAtoms
[ NET_SUPPORTING_WM_CHECK
],
765 && aRealType
== XA_WINDOW
769 if ( ! GetGenericUnixSalData()->ErrorTrapPop( false ) )
771 GetGenericUnixSalData()->ErrorTrapPush();
772 ::Window aCheckWindow
= *reinterpret_cast< ::Window
* >(pProperty
);
775 if( aCheckWindow
== aWMChild
)
779 m_aWMAtoms
[ UTF8_STRING
] = XInternAtom( m_pDisplay
, "UTF8_STRING", False
);
780 if( XGetWindowProperty( m_pDisplay
,
782 m_aWMAtoms
[ NET_WM_NAME
],
785 AnyPropertyType
, /* m_aWMAtoms[ UTF8_STRING ],*/
794 if (aRealType
== m_aWMAtoms
[ UTF8_STRING
])
795 m_aWMName
= OUString( reinterpret_cast<char*>(pProperty
), nItems
, RTL_TEXTENCODING_UTF8
);
796 else if (aRealType
== XA_STRING
)
797 m_aWMName
= OUString( reinterpret_cast<char*>(pProperty
), nItems
, RTL_TEXTENCODING_ISO_8859_1
);
808 // if this is metacity, check for version to enable a legacy workaround
809 if( m_aWMName
== "Metacity" )
811 int nVersionMajor
= 0, nVersionMinor
= 0;
812 Atom nVersionAtom
= XInternAtom( m_pDisplay
, "_METACITY_VERSION", True
);
815 if( XGetWindowProperty( m_pDisplay
,
820 m_aWMAtoms
[ UTF8_STRING
],
829 OUString
aMetaVersion( reinterpret_cast<char*>(pProperty
), nItems
, RTL_TEXTENCODING_UTF8
);
831 nVersionMajor
= aMetaVersion
.getToken(0, '.', nIdx
).toInt32();
832 nVersionMinor
= aMetaVersion
.getToken(0, '.', nIdx
).toInt32();
840 if( nVersionMajor
< 2 || (nVersionMajor
== 2 && nVersionMinor
< 12) )
841 m_bLegacyPartialFullscreen
= true;
852 GetGenericUnixSalData()->ErrorTrapPush();
856 GetGenericUnixSalData()->ErrorTrapPop();
867 bool WMAdaptor::getWMshouldSwitchWorkspace() const
869 if( ! m_bWMshouldSwitchWorkspaceInit
)
871 WMAdaptor
* pWMA
= const_cast<WMAdaptor
*>(this);
873 pWMA
->m_bWMshouldSwitchWorkspace
= true;
874 vcl::SettingsConfigItem
* pItem
= vcl::SettingsConfigItem::get();
875 OUString
aSetting( pItem
->getValue( "WM",
876 "ShouldSwitchWorkspace" ) );
877 if( aSetting
.isEmpty() )
879 if( m_aWMName
== "awesome" )
881 pWMA
->m_bWMshouldSwitchWorkspace
= false;
885 pWMA
->m_bWMshouldSwitchWorkspace
= aSetting
.toBoolean();
886 pWMA
->m_bWMshouldSwitchWorkspaceInit
= true;
888 return m_bWMshouldSwitchWorkspace
;
892 * WMAdaptor::isValid()
894 bool WMAdaptor::isValid() const
900 * NetWMAdaptor::isValid()
902 bool NetWMAdaptor::isValid() const
904 // some necessary sanity checks; there are WMs out there
905 // which implement some of the WM hints spec without
906 // real functionality
908 m_aWMAtoms
[ NET_SUPPORTED
]
909 && m_aWMAtoms
[ NET_SUPPORTING_WM_CHECK
]
910 && m_aWMAtoms
[ NET_WM_NAME
]
911 && m_aWMAtoms
[ NET_WM_WINDOW_TYPE_NORMAL
]
912 && m_aWMAtoms
[ NET_WM_WINDOW_TYPE_DIALOG
]
917 * GnomeWMAdaptor::isValid()
919 bool GnomeWMAdaptor::isValid() const
925 * WMAdaptor::initAtoms
928 void WMAdaptor::initAtoms()
931 for(const WMAdaptorProtocol
& i
: aAtomTab
)
932 m_aWMAtoms
[ i
.nProtocol
] = XInternAtom( m_pDisplay
, i
.pProtocol
, False
);
933 m_aWMAtoms
[ NET_SUPPORTING_WM_CHECK
] = XInternAtom( m_pDisplay
, "_NET_SUPPORTING_WM_CHECK", True
);
934 m_aWMAtoms
[ NET_WM_NAME
] = XInternAtom( m_pDisplay
, "_NET_WM_NAME", True
);
938 * NetWMAdaptor::initAtoms
941 void NetWMAdaptor::initAtoms()
943 WMAdaptor::initAtoms();
945 m_aWMAtoms
[ NET_SUPPORTED
] = XInternAtom( m_pDisplay
, "_NET_SUPPORTED", True
);
949 * GnomeWMAdaptor::initAtoms
952 void GnomeWMAdaptor::initAtoms()
954 WMAdaptor::initAtoms();
956 m_aWMAtoms
[ WIN_PROTOCOLS
] = XInternAtom( m_pDisplay
, "_WIN_PROTOCOLS", True
);
957 m_aWMAtoms
[ WIN_SUPPORTING_WM_CHECK
] = XInternAtom( m_pDisplay
, "_WIN_SUPPORTING_WM_CHECK", True
);
961 * WMAdaptor::setWMName
966 void WMAdaptor::setWMName( X11SalFrame
* pFrame
, const OUString
& rWMName
) const
968 OString
aTitle(OUStringToOString(rWMName
,
969 osl_getThreadTextEncoding()));
972 rtl_Locale
* pLocale
= nullptr;
973 osl_getProcessLocale( &pLocale
);
976 OUString
aLocaleString( LanguageTag( *pLocale
).getGlibcLocaleString( OUString()));
977 aWMLocale
= OUStringToOString( aLocaleString
, RTL_TEXTENCODING_ISO_8859_1
);
981 static const char* pLang
= getenv( "LANG" );
982 aWMLocale
= pLang
? pLang
: "C";
985 char* pT
= const_cast<char*>(aTitle
.getStr());
986 XTextProperty aProp
= { nullptr, None
, 0, 0 };
987 XmbTextListToTextProperty( m_pDisplay
,
993 unsigned char const * pData
= aProp
.nitems
? aProp
.value
: reinterpret_cast<unsigned char const *>(aTitle
.getStr());
994 Atom nType
= aProp
.nitems
? aProp
.encoding
: XA_STRING
;
995 int nFormat
= aProp
.nitems
? aProp
.format
: 8;
996 int nBytes
= aProp
.nitems
? aProp
.nitems
: aTitle
.getLength();
997 const SystemEnvData
* pEnv
= pFrame
->GetSystemData();
998 XChangeProperty( m_pDisplay
,
999 static_cast<::Window
>(pEnv
->aShellWindow
),
1006 XChangeProperty( m_pDisplay
,
1007 static_cast<::Window
>(pEnv
->aShellWindow
),
1014 XChangeProperty( m_pDisplay
,
1015 static_cast<::Window
>(pEnv
->aShellWindow
),
1016 m_aWMAtoms
[ WM_LOCALE_NAME
],
1020 reinterpret_cast<unsigned char const *>(aWMLocale
.getStr()),
1021 aWMLocale
.getLength() );
1022 if (aProp
.value
!= nullptr)
1023 XFree( aProp
.value
);
1027 * NetWMAdaptor::setWMName
1033 void NetWMAdaptor::setWMName( X11SalFrame
* pFrame
, const OUString
& rWMName
) const
1035 WMAdaptor::setWMName( pFrame
, rWMName
);
1037 OString
aTitle(OUStringToOString(rWMName
, RTL_TEXTENCODING_UTF8
));
1038 const SystemEnvData
* pEnv
= pFrame
->GetSystemData();
1039 if( m_aWMAtoms
[ NET_WM_NAME
] )
1040 XChangeProperty( m_pDisplay
,
1041 static_cast<::Window
>(pEnv
->aShellWindow
),
1042 m_aWMAtoms
[ NET_WM_NAME
],
1043 m_aWMAtoms
[ UTF8_STRING
],
1046 reinterpret_cast<unsigned char const *>(aTitle
.getStr()),
1047 aTitle
.getLength() );
1048 if( m_aWMAtoms
[ NET_WM_ICON_NAME
] )
1049 XChangeProperty( m_pDisplay
,
1050 static_cast<::Window
>(pEnv
->aShellWindow
),
1051 m_aWMAtoms
[ NET_WM_ICON_NAME
],
1052 m_aWMAtoms
[ UTF8_STRING
],
1055 reinterpret_cast<unsigned char const *>(aTitle
.getStr()),
1056 aTitle
.getLength() );
1060 * NetWMAdaptor::setNetWMState
1061 * sets _NET_WM_STATE
1063 void NetWMAdaptor::setNetWMState( X11SalFrame
* pFrame
) const
1065 if( !(m_aWMAtoms
[ NET_WM_STATE
]) )
1068 Atom aStateAtoms
[ 10 ];
1069 int nStateAtoms
= 0;
1071 // set NET_WM_STATE_MODAL
1072 if( pFrame
->mbMaximizedVert
1073 && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
] )
1074 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
];
1075 if( pFrame
->mbMaximizedHorz
1076 && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
] )
1077 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
];
1078 if( pFrame
->bAlwaysOnTop_
&& m_aWMAtoms
[ NET_WM_STATE_STAYS_ON_TOP
] )
1079 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_STAYS_ON_TOP
];
1080 if( pFrame
->mbShaded
&& m_aWMAtoms
[ NET_WM_STATE_SHADED
] )
1081 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_SHADED
];
1082 if( pFrame
->mbFullScreen
&& m_aWMAtoms
[ NET_WM_STATE_FULLSCREEN
] )
1083 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_FULLSCREEN
];
1084 if( pFrame
->meWindowType
== WMWindowType::Utility
&& m_aWMAtoms
[ NET_WM_STATE_SKIP_TASKBAR
] )
1085 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_SKIP_TASKBAR
];
1089 XChangeProperty( m_pDisplay
,
1090 pFrame
->GetShellWindow(),
1091 m_aWMAtoms
[ NET_WM_STATE
],
1095 reinterpret_cast<unsigned char*>(aStateAtoms
),
1100 XDeleteProperty( m_pDisplay
,
1101 pFrame
->GetShellWindow(),
1102 m_aWMAtoms
[ NET_WM_STATE
] );
1103 if( !pFrame
->mbMaximizedHorz
1104 || !pFrame
->mbMaximizedVert
1105 || ( pFrame
->nStyle_
& SalFrameStyleFlags::SIZEABLE
) )
1109 * for maximizing use NorthWestGravity (including decoration)
1112 tools::Long supplied
;
1114 if( XGetWMNormalHints( m_pDisplay
,
1115 pFrame
->GetShellWindow(),
1120 hints
.flags
|= PWinGravity
;
1121 hints
.win_gravity
= NorthWestGravity
;
1122 XSetWMNormalHints( m_pDisplay
,
1123 pFrame
->GetShellWindow(),
1125 XSync( m_pDisplay
, False
);
1128 // SetPosSize necessary to set width/height, min/max w/h
1129 sal_Int32 nCurrent
= 0;
1131 * get current desktop here if work areas have different size
1132 * (does this happen on any platform ?)
1134 if( ! m_bEqualWorkAreas
)
1136 nCurrent
= getCurrentWorkArea();
1140 tools::Rectangle aPosSize
= m_aWMWorkAreas
[nCurrent
];
1141 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
1142 aPosSize
= tools::Rectangle( Point( aPosSize
.Left() + rGeom
.nLeftDecoration
,
1143 aPosSize
.Top() + rGeom
.nTopDecoration
),
1144 Size( aPosSize
.GetWidth()
1145 - rGeom
.nLeftDecoration
1146 - rGeom
.nRightDecoration
,
1147 aPosSize
.GetHeight()
1148 - rGeom
.nTopDecoration
1149 - rGeom
.nBottomDecoration
)
1151 pFrame
->SetPosSize( aPosSize
);
1154 * reset gravity hint to static gravity
1155 * (this should not move window according to ICCCM)
1157 if( bHint
&& pFrame
->nShowState_
!= SHOWSTATE_UNKNOWN
)
1159 hints
.win_gravity
= StaticGravity
;
1160 XSetWMNormalHints( m_pDisplay
,
1161 pFrame
->GetShellWindow(),
1167 * GnomeWMAdaptor::setNetWMState
1170 void GnomeWMAdaptor::setGnomeWMState( X11SalFrame
* pFrame
) const
1172 if( !(m_aWMAtoms
[ WIN_STATE
]) )
1175 sal_uInt32 nWinWMState
= 0;
1177 if( pFrame
->mbMaximizedVert
)
1178 nWinWMState
|= 1 << 2;
1179 if( pFrame
->mbMaximizedHorz
)
1180 nWinWMState
|= 1 << 3;
1181 if( pFrame
->mbShaded
)
1182 nWinWMState
|= 1 << 5;
1184 XChangeProperty( m_pDisplay
,
1185 pFrame
->GetShellWindow(),
1186 m_aWMAtoms
[ WIN_STATE
],
1190 reinterpret_cast<unsigned char*>(&nWinWMState
),
1193 if( !pFrame
->mbMaximizedHorz
1194 || !pFrame
->mbMaximizedVert
1195 || ( pFrame
->nStyle_
& SalFrameStyleFlags::SIZEABLE
) )
1199 * for maximizing use NorthWestGravity (including decoration)
1202 tools::Long supplied
;
1204 if( XGetWMNormalHints( m_pDisplay
,
1205 pFrame
->GetShellWindow(),
1210 hints
.flags
|= PWinGravity
;
1211 hints
.win_gravity
= NorthWestGravity
;
1212 XSetWMNormalHints( m_pDisplay
,
1213 pFrame
->GetShellWindow(),
1215 XSync( m_pDisplay
, False
);
1218 // SetPosSize necessary to set width/height, min/max w/h
1219 sal_Int32 nCurrent
= 0;
1221 * get current desktop here if work areas have different size
1222 * (does this happen on any platform ?)
1224 if( ! m_bEqualWorkAreas
)
1226 nCurrent
= getCurrentWorkArea();
1230 tools::Rectangle aPosSize
= m_aWMWorkAreas
[nCurrent
];
1231 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
1232 aPosSize
= tools::Rectangle( Point( aPosSize
.Left() + rGeom
.nLeftDecoration
,
1233 aPosSize
.Top() + rGeom
.nTopDecoration
),
1234 Size( aPosSize
.GetWidth()
1235 - rGeom
.nLeftDecoration
1236 - rGeom
.nRightDecoration
,
1237 aPosSize
.GetHeight()
1238 - rGeom
.nTopDecoration
1239 - rGeom
.nBottomDecoration
)
1241 pFrame
->SetPosSize( aPosSize
);
1244 * reset gravity hint to static gravity
1245 * (this should not move window according to ICCCM)
1247 if( bHint
&& pFrame
->nShowState_
!= SHOWSTATE_UNKNOWN
)
1249 hints
.win_gravity
= StaticGravity
;
1250 XSetWMNormalHints( m_pDisplay
,
1251 pFrame
->GetShellWindow(),
1257 * WMAdaptor::setFrameDecoration
1258 * sets _MOTIF_WM_HINTS
1262 void WMAdaptor::setFrameTypeAndDecoration( X11SalFrame
* pFrame
, WMWindowType eType
, int nDecorationFlags
, X11SalFrame
* pReferenceFrame
) const
1264 pFrame
->meWindowType
= eType
;
1266 if( ! pFrame
->mbFullScreen
)
1270 unsigned long flags
, func
, deco
;
1271 tools::Long input_mode
;
1272 unsigned long status
;
1275 aHint
.flags
= 15; /* flags for functions, decoration, input mode and status */
1277 aHint
.func
= 1 << 2;
1279 aHint
.input_mode
= 0;
1281 // evaluate decoration flags
1282 if( nDecorationFlags
& decoration_All
)
1289 if( nDecorationFlags
& decoration_Title
)
1290 aHint
.deco
|= 1 << 3;
1291 if( nDecorationFlags
& decoration_Border
)
1292 aHint
.deco
|= 1 << 1;
1293 if( nDecorationFlags
& decoration_Resize
)
1295 aHint
.deco
|= 1 << 2;
1296 aHint
.func
|= 1 << 1;
1298 if( nDecorationFlags
& decoration_MinimizeBtn
)
1300 aHint
.deco
|= 1 << 5;
1301 aHint
.func
|= 1 << 3;
1303 if( nDecorationFlags
& decoration_MaximizeBtn
)
1305 aHint
.deco
|= 1 << 6;
1306 aHint
.func
|= 1 << 4;
1308 if( nDecorationFlags
& decoration_CloseBtn
)
1310 aHint
.deco
|= 1 << 4;
1311 aHint
.func
|= 1 << 5;
1316 XChangeProperty( m_pDisplay
,
1317 pFrame
->GetShellWindow(),
1318 m_aWMAtoms
[ MOTIF_WM_HINTS
],
1319 m_aWMAtoms
[ MOTIF_WM_HINTS
],
1322 reinterpret_cast<unsigned char*>(&aHint
),
1326 // set transientFor hint
1327 /* #91030# dtwm will not map a dialogue if the transient
1328 * window is iconified. This is deemed undesirable because
1329 * message boxes do not get mapped, so use the root as transient
1332 if( pReferenceFrame
)
1334 XSetTransientForHint( m_pDisplay
,
1335 pFrame
->GetShellWindow(),
1336 pReferenceFrame
->bMapped_
?
1337 pReferenceFrame
->GetShellWindow() :
1338 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() )
1340 if( ! pReferenceFrame
->bMapped_
)
1341 pFrame
->mbTransientForRoot
= true;
1346 * NetWMAdaptor::setFrameDecoration
1347 * sets _MOTIF_WM_HINTS
1348 * _NET_WM_WINDOW_TYPE
1353 void NetWMAdaptor::setFrameTypeAndDecoration( X11SalFrame
* pFrame
, WMWindowType eType
, int nDecorationFlags
, X11SalFrame
* pReferenceFrame
) const
1355 WMAdaptor::setFrameTypeAndDecoration( pFrame
, eType
, nDecorationFlags
, pReferenceFrame
);
1357 setNetWMState( pFrame
);
1359 // set NET_WM_WINDOW_TYPE
1360 if( m_aWMAtoms
[ NET_WM_WINDOW_TYPE
] )
1362 Atom aWindowTypes
[4];
1363 int nWindowTypes
= 0;
1366 case WMWindowType::Utility
:
1367 aWindowTypes
[nWindowTypes
++] =
1368 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_UTILITY
] ?
1369 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_UTILITY
] :
1370 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_DIALOG
];
1372 case WMWindowType::ModelessDialogue
:
1373 aWindowTypes
[nWindowTypes
++] =
1374 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_DIALOG
];
1376 case WMWindowType::Splash
:
1377 aWindowTypes
[nWindowTypes
++] =
1378 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_SPLASH
] ?
1379 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_SPLASH
] :
1380 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_NORMAL
];
1382 case WMWindowType::Toolbar
:
1383 if( m_aWMAtoms
[ KDE_NET_WM_WINDOW_TYPE_OVERRIDE
] )
1384 aWindowTypes
[nWindowTypes
++] = m_aWMAtoms
[ KDE_NET_WM_WINDOW_TYPE_OVERRIDE
];
1385 aWindowTypes
[nWindowTypes
++] =
1386 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_TOOLBAR
] ?
1387 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_TOOLBAR
] :
1388 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_NORMAL
];
1390 case WMWindowType::Dock
:
1391 aWindowTypes
[nWindowTypes
++] =
1392 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_DOCK
] ?
1393 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_DOCK
] :
1394 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_NORMAL
];
1397 aWindowTypes
[nWindowTypes
++] = m_aWMAtoms
[ NET_WM_WINDOW_TYPE_NORMAL
];
1400 XChangeProperty( m_pDisplay
,
1401 pFrame
->GetShellWindow(),
1402 m_aWMAtoms
[ NET_WM_WINDOW_TYPE
],
1406 reinterpret_cast<unsigned char*>(aWindowTypes
),
1409 if( ( eType
== WMWindowType::ModelessDialogue
)
1410 && ! pReferenceFrame
)
1412 XSetTransientForHint( m_pDisplay
,
1413 pFrame
->GetShellWindow(),
1414 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ) );
1415 pFrame
->mbTransientForRoot
= true;
1420 * WMAdaptor::maximizeFrame
1423 void WMAdaptor::maximizeFrame( X11SalFrame
* pFrame
, bool bHorizontal
, bool bVertical
) const
1425 pFrame
->mbMaximizedVert
= bVertical
;
1426 pFrame
->mbMaximizedHorz
= bHorizontal
;
1428 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
1430 // discard pending configure notifies for this frame
1431 XSync( m_pDisplay
, False
);
1433 while( XCheckTypedWindowEvent( m_pDisplay
,
1434 pFrame
->GetShellWindow(),
1438 while( XCheckTypedWindowEvent( m_pDisplay
,
1439 pFrame
->GetWindow(),
1444 if( bHorizontal
|| bVertical
)
1446 Size
aScreenSize( m_pSalDisplay
->GetScreenSize( pFrame
->GetScreenNumber() ) );
1447 Point
aTL( rGeom
.nLeftDecoration
, rGeom
.nTopDecoration
);
1448 if( m_pSalDisplay
->IsXinerama() )
1450 Point
aMed( aTL
.X() + rGeom
.nWidth
/2, aTL
.Y() + rGeom
.nHeight
/2 );
1451 const std::vector
< tools::Rectangle
>& rScreens
= m_pSalDisplay
->GetXineramaScreens();
1452 for(const auto & rScreen
: rScreens
)
1453 if( rScreen
.IsInside( aMed
) )
1455 aTL
+= rScreen
.TopLeft();
1456 aScreenSize
= rScreen
.GetSize();
1460 tools::Rectangle
aTarget( aTL
,
1461 Size( aScreenSize
.Width() - rGeom
.nLeftDecoration
- rGeom
.nTopDecoration
,
1462 aScreenSize
.Height() - rGeom
.nTopDecoration
- rGeom
.nBottomDecoration
)
1468 pFrame
->maRestorePosSize
.IsEmpty() ?
1469 rGeom
.nWidth
: pFrame
->maRestorePosSize
.GetWidth(),
1474 pFrame
->maRestorePosSize
.IsEmpty() ?
1475 rGeom
.nX
: pFrame
->maRestorePosSize
.Left() );
1477 else if( ! bVertical
)
1482 pFrame
->maRestorePosSize
.IsEmpty() ?
1483 rGeom
.nHeight
: pFrame
->maRestorePosSize
.GetHeight()
1487 pFrame
->maRestorePosSize
.IsEmpty() ?
1488 rGeom
.nY
: pFrame
->maRestorePosSize
.Top() );
1491 tools::Rectangle
aRestore( Point( rGeom
.nX
, rGeom
.nY
), Size( rGeom
.nWidth
, rGeom
.nHeight
) );
1492 if( pFrame
->bMapped_
)
1494 XSetInputFocus( m_pDisplay
,
1495 pFrame
->GetShellWindow(),
1501 if( pFrame
->maRestorePosSize
.IsEmpty() )
1502 pFrame
->maRestorePosSize
= aRestore
;
1504 pFrame
->SetPosSize( aTarget
);
1505 pFrame
->nWidth_
= aTarget
.GetWidth();
1506 pFrame
->nHeight_
= aTarget
.GetHeight();
1507 XRaiseWindow( m_pDisplay
,
1508 pFrame
->GetShellWindow()
1510 if( pFrame
->GetStackingWindow() )
1511 XRaiseWindow( m_pDisplay
,
1512 pFrame
->GetStackingWindow()
1518 pFrame
->SetPosSize( pFrame
->maRestorePosSize
);
1519 pFrame
->maRestorePosSize
= tools::Rectangle();
1520 pFrame
->nWidth_
= rGeom
.nWidth
;
1521 pFrame
->nHeight_
= rGeom
.nHeight
;
1526 * NetWMAdaptor::maximizeFrame
1527 * changes _NET_WM_STATE by sending a client message
1530 void NetWMAdaptor::maximizeFrame( X11SalFrame
* pFrame
, bool bHorizontal
, bool bVertical
) const
1532 pFrame
->mbMaximizedVert
= bVertical
;
1533 pFrame
->mbMaximizedHorz
= bHorizontal
;
1535 if( m_aWMAtoms
[ NET_WM_STATE
]
1536 && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
]
1537 && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
]
1538 && ( pFrame
->nStyle_
& ~SalFrameStyleFlags::DEFAULT
)
1541 if( pFrame
->bMapped_
)
1543 // window already mapped, send WM a message
1545 aEvent
.type
= ClientMessage
;
1546 aEvent
.xclient
.display
= m_pDisplay
;
1547 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
1548 aEvent
.xclient
.message_type
= m_aWMAtoms
[ NET_WM_STATE
];
1549 aEvent
.xclient
.format
= 32;
1550 aEvent
.xclient
.data
.l
[0] = bHorizontal
? 1 : 0;
1551 aEvent
.xclient
.data
.l
[1] = m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
];
1552 aEvent
.xclient
.data
.l
[2] = bHorizontal
== bVertical
? m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
] : 0;
1553 aEvent
.xclient
.data
.l
[3] = 0;
1554 aEvent
.xclient
.data
.l
[4] = 0;
1555 XSendEvent( m_pDisplay
,
1556 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1558 SubstructureNotifyMask
| SubstructureRedirectMask
,
1561 if( bHorizontal
!= bVertical
)
1563 aEvent
.xclient
.data
.l
[0]= bVertical
? 1 : 0;
1564 aEvent
.xclient
.data
.l
[1]= m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
];
1565 aEvent
.xclient
.data
.l
[2]= 0;
1566 XSendEvent( m_pDisplay
,
1567 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1569 SubstructureNotifyMask
| SubstructureRedirectMask
,
1576 // window not mapped yet, set _NET_WM_STATE directly
1577 setNetWMState( pFrame
);
1579 if( !bHorizontal
&& !bVertical
)
1580 pFrame
->maRestorePosSize
= tools::Rectangle();
1581 else if( pFrame
->maRestorePosSize
.IsEmpty() )
1583 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
1584 pFrame
->maRestorePosSize
=
1585 tools::Rectangle( Point( rGeom
.nX
, rGeom
.nY
), Size( rGeom
.nWidth
, rGeom
.nHeight
) );
1589 WMAdaptor::maximizeFrame( pFrame
, bHorizontal
, bVertical
);
1593 * GnomeWMAdaptor::maximizeFrame
1594 * changes _WIN_STATE by sending a client message
1597 void GnomeWMAdaptor::maximizeFrame( X11SalFrame
* pFrame
, bool bHorizontal
, bool bVertical
) const
1599 pFrame
->mbMaximizedVert
= bVertical
;
1600 pFrame
->mbMaximizedHorz
= bHorizontal
;
1602 if( m_aWMAtoms
[ WIN_STATE
]
1603 && ( pFrame
->nStyle_
& ~SalFrameStyleFlags::DEFAULT
)
1606 if( pFrame
->bMapped_
)
1608 // window already mapped, send WM a message
1610 aEvent
.type
= ClientMessage
;
1611 aEvent
.xclient
.display
= m_pDisplay
;
1612 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
1613 aEvent
.xclient
.message_type
= m_aWMAtoms
[ WIN_STATE
];
1614 aEvent
.xclient
.format
= 32;
1615 aEvent
.xclient
.data
.l
[0] = (1<<2)|(1<<3);
1616 aEvent
.xclient
.data
.l
[1] =
1617 (bVertical
? (1<<2) : 0)
1618 | (bHorizontal
? (1<<3) : 0);
1619 aEvent
.xclient
.data
.l
[2] = 0;
1620 aEvent
.xclient
.data
.l
[3] = 0;
1621 aEvent
.xclient
.data
.l
[4] = 0;
1622 XSendEvent( m_pDisplay
,
1623 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1625 SubstructureNotifyMask
,
1630 // window not mapped yet, set _WIN_STATE directly
1631 setGnomeWMState( pFrame
);
1633 if( !bHorizontal
&& !bVertical
)
1634 pFrame
->maRestorePosSize
= tools::Rectangle();
1635 else if( pFrame
->maRestorePosSize
.IsEmpty() )
1637 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
1638 pFrame
->maRestorePosSize
=
1639 tools::Rectangle( Point( rGeom
.nX
, rGeom
.nY
), Size( rGeom
.nWidth
, rGeom
.nHeight
) );
1643 WMAdaptor::maximizeFrame( pFrame
, bHorizontal
, bVertical
);
1647 * WMAdaptor::enableAlwaysOnTop
1649 void WMAdaptor::enableAlwaysOnTop( X11SalFrame
*, bool /*bEnable*/ ) const
1654 * NetWMAdaptor::enableAlwaysOnTop
1656 void NetWMAdaptor::enableAlwaysOnTop( X11SalFrame
* pFrame
, bool bEnable
) const
1658 pFrame
->bAlwaysOnTop_
= bEnable
;
1659 if( !(m_aWMAtoms
[ NET_WM_STATE_STAYS_ON_TOP
]) )
1662 if( pFrame
->bMapped_
)
1664 // window already mapped, send WM a message
1666 aEvent
.type
= ClientMessage
;
1667 aEvent
.xclient
.display
= m_pDisplay
;
1668 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
1669 aEvent
.xclient
.message_type
= m_aWMAtoms
[ NET_WM_STATE
];
1670 aEvent
.xclient
.format
= 32;
1671 aEvent
.xclient
.data
.l
[0] = bEnable
? 1 : 0;
1672 aEvent
.xclient
.data
.l
[1] = m_aWMAtoms
[ NET_WM_STATE_STAYS_ON_TOP
];
1673 aEvent
.xclient
.data
.l
[2] = 0;
1674 aEvent
.xclient
.data
.l
[3] = 0;
1675 aEvent
.xclient
.data
.l
[4] = 0;
1676 XSendEvent( m_pDisplay
,
1677 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1679 SubstructureNotifyMask
| SubstructureRedirectMask
,
1684 setNetWMState( pFrame
);
1688 * GnomeWMAdaptor::enableAlwaysOnTop
1690 void GnomeWMAdaptor::enableAlwaysOnTop( X11SalFrame
* pFrame
, bool bEnable
) const
1692 pFrame
->bAlwaysOnTop_
= bEnable
;
1693 if( !(m_aWMAtoms
[ WIN_LAYER
]) )
1696 if( pFrame
->bMapped_
)
1698 // window already mapped, send WM a message
1700 aEvent
.type
= ClientMessage
;
1701 aEvent
.xclient
.display
= m_pDisplay
;
1702 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
1703 aEvent
.xclient
.message_type
= m_aWMAtoms
[ WIN_LAYER
];
1704 aEvent
.xclient
.format
= 32;
1705 aEvent
.xclient
.data
.l
[0] = bEnable
? 6 : 4;
1706 aEvent
.xclient
.data
.l
[1] = 0;
1707 aEvent
.xclient
.data
.l
[2] = 0;
1708 aEvent
.xclient
.data
.l
[3] = 0;
1709 aEvent
.xclient
.data
.l
[4] = 0;
1710 XSendEvent( m_pDisplay
,
1711 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1713 SubstructureNotifyMask
| SubstructureRedirectMask
,
1719 sal_uInt32 nNewLayer
= bEnable
? 6 : 4;
1720 XChangeProperty( m_pDisplay
,
1721 pFrame
->GetShellWindow(),
1722 m_aWMAtoms
[ WIN_LAYER
],
1726 reinterpret_cast<unsigned char*>(&nNewLayer
),
1733 * WMAdaptor::changeReferenceFrame
1735 void WMAdaptor::changeReferenceFrame( X11SalFrame
* pFrame
, X11SalFrame
const * pReferenceFrame
) const
1737 if( ( pFrame
->nStyle_
& SalFrameStyleFlags::PLUG
)
1738 || pFrame
->IsOverrideRedirect()
1739 || pFrame
->IsFloatGrabWindow()
1743 ::Window aTransient
= pFrame
->pDisplay_
->GetRootWindow( pFrame
->GetScreenNumber() );
1744 pFrame
->mbTransientForRoot
= true;
1745 if( pReferenceFrame
)
1747 aTransient
= pReferenceFrame
->GetShellWindow();
1748 pFrame
->mbTransientForRoot
= false;
1750 XSetTransientForHint( m_pDisplay
,
1751 pFrame
->GetShellWindow(),
1756 * WMAdaptor::handlePropertyNotify
1758 int WMAdaptor::handlePropertyNotify( X11SalFrame
*, XPropertyEvent
* ) const
1764 * NetWMAdaptor::handlePropertyNotify
1766 int NetWMAdaptor::handlePropertyNotify( X11SalFrame
* pFrame
, XPropertyEvent
* pEvent
) const
1769 if( pEvent
->atom
== m_aWMAtoms
[ NET_WM_STATE
] )
1771 pFrame
->mbMaximizedHorz
= pFrame
->mbMaximizedVert
= false;
1772 pFrame
->mbShaded
= false;
1774 if( pEvent
->state
== PropertyNewValue
)
1776 Atom nType
, *pStates
;
1778 unsigned long nItems
, nBytesLeft
;
1779 unsigned char* pData
= nullptr;
1780 tools::Long nOffset
= 0;
1783 XGetWindowProperty( m_pDisplay
,
1785 m_aWMAtoms
[ NET_WM_STATE
],
1791 &nItems
, &nBytesLeft
,
1795 if( nType
== XA_ATOM
&& nFormat
== 32 && nItems
> 0 )
1797 pStates
= reinterpret_cast<Atom
*>(pData
);
1798 for( unsigned long i
= 0; i
< nItems
; i
++ )
1800 if( pStates
[i
] == m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
] && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
] )
1801 pFrame
->mbMaximizedVert
= true;
1802 else if( pStates
[i
] == m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
] && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
] )
1803 pFrame
->mbMaximizedHorz
= true;
1804 else if( pStates
[i
] == m_aWMAtoms
[ NET_WM_STATE_SHADED
] && m_aWMAtoms
[ NET_WM_STATE_SHADED
] )
1805 pFrame
->mbShaded
= true;
1810 nOffset
+= nItems
* nFormat
/ 32;
1814 } while( nBytesLeft
> 0 );
1817 if( ! (pFrame
->mbMaximizedHorz
|| pFrame
->mbMaximizedVert
) )
1818 pFrame
->maRestorePosSize
= tools::Rectangle();
1821 const SalFrameGeometry
& rGeom
= pFrame
->GetUnmirroredGeometry();
1822 // the current geometry may already be changed by the corresponding
1823 // ConfigureNotify, but this cannot be helped
1824 pFrame
->maRestorePosSize
=
1825 tools::Rectangle( Point( rGeom
.nX
, rGeom
.nY
),
1826 Size( rGeom
.nWidth
, rGeom
.nHeight
) );
1829 else if( pEvent
->atom
== m_aWMAtoms
[ NET_WM_DESKTOP
] )
1831 pFrame
->m_nWorkArea
= getWindowWorkArea( pFrame
->GetShellWindow() );
1840 * GnomeWMAdaptor::handlePropertyNotify
1842 int GnomeWMAdaptor::handlePropertyNotify( X11SalFrame
* pFrame
, XPropertyEvent
* pEvent
) const
1845 if( pEvent
->atom
== m_aWMAtoms
[ WIN_STATE
] )
1847 pFrame
->mbMaximizedHorz
= pFrame
->mbMaximizedVert
= false;
1848 pFrame
->mbShaded
= false;
1850 if( pEvent
->state
== PropertyNewValue
)
1854 unsigned long nItems
= 0;
1855 unsigned long nBytesLeft
= 0;
1856 unsigned char* pData
= nullptr;
1857 XGetWindowProperty( m_pDisplay
,
1859 m_aWMAtoms
[ WIN_STATE
],
1865 &nItems
, &nBytesLeft
,
1869 if( nType
== XA_CARDINAL
&& nFormat
== 32 && nItems
== 1 )
1871 sal_uInt32 nWinState
= *reinterpret_cast<sal_uInt32
*>(pData
);
1872 if( nWinState
& (1<<2) )
1873 pFrame
->mbMaximizedVert
= true;
1874 if( nWinState
& (1<<3) )
1875 pFrame
->mbMaximizedHorz
= true;
1876 if( nWinState
& (1<<5) )
1877 pFrame
->mbShaded
= true;
1883 if( ! (pFrame
->mbMaximizedHorz
|| pFrame
->mbMaximizedVert
) )
1884 pFrame
->maRestorePosSize
= tools::Rectangle();
1887 const SalFrameGeometry
& rGeom
= pFrame
->GetUnmirroredGeometry();
1888 // the current geometry may already be changed by the corresponding
1889 // ConfigureNotify, but this cannot be helped
1890 pFrame
->maRestorePosSize
=
1891 tools::Rectangle( Point( rGeom
.nX
, rGeom
.nY
),
1892 Size( rGeom
.nWidth
, rGeom
.nHeight
) );
1895 else if( pEvent
->atom
== m_aWMAtoms
[ NET_WM_DESKTOP
] )
1897 pFrame
->m_nWorkArea
= getWindowWorkArea( pFrame
->GetShellWindow() );
1908 void WMAdaptor::shade( X11SalFrame
*, bool /*bToShaded*/ ) const
1913 * NetWMAdaptor::shade
1915 void NetWMAdaptor::shade( X11SalFrame
* pFrame
, bool bToShaded
) const
1917 if( !(m_aWMAtoms
[ NET_WM_STATE
]
1918 && m_aWMAtoms
[ NET_WM_STATE_SHADED
]
1919 && ( pFrame
->nStyle_
& ~SalFrameStyleFlags::DEFAULT
))
1923 pFrame
->mbShaded
= bToShaded
;
1924 if( pFrame
->bMapped_
)
1926 // window already mapped, send WM a message
1928 aEvent
.type
= ClientMessage
;
1929 aEvent
.xclient
.display
= m_pDisplay
;
1930 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
1931 aEvent
.xclient
.message_type
= m_aWMAtoms
[ NET_WM_STATE
];
1932 aEvent
.xclient
.format
= 32;
1933 aEvent
.xclient
.data
.l
[0] = bToShaded
? 1 : 0;
1934 aEvent
.xclient
.data
.l
[1] = m_aWMAtoms
[ NET_WM_STATE_SHADED
];
1935 aEvent
.xclient
.data
.l
[2] = 0;
1936 aEvent
.xclient
.data
.l
[3] = 0;
1937 aEvent
.xclient
.data
.l
[4] = 0;
1938 XSendEvent( m_pDisplay
,
1939 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1941 SubstructureNotifyMask
| SubstructureRedirectMask
,
1947 // window not mapped yet, set _NET_WM_STATE directly
1948 setNetWMState( pFrame
);
1953 * GnomeWMAdaptor::shade
1955 void GnomeWMAdaptor::shade( X11SalFrame
* pFrame
, bool bToShaded
) const
1957 if( !(m_aWMAtoms
[ WIN_STATE
]) )
1960 pFrame
->mbShaded
= bToShaded
;
1961 if( pFrame
->bMapped_
)
1963 // window already mapped, send WM a message
1965 aEvent
.type
= ClientMessage
;
1966 aEvent
.xclient
.display
= m_pDisplay
;
1967 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
1968 aEvent
.xclient
.message_type
= m_aWMAtoms
[ WIN_STATE
];
1969 aEvent
.xclient
.format
= 32;
1970 aEvent
.xclient
.data
.l
[0] = (1<<5);
1971 aEvent
.xclient
.data
.l
[1] = bToShaded
? (1<<5) : 0;
1972 aEvent
.xclient
.data
.l
[2] = 0;
1973 aEvent
.xclient
.data
.l
[3] = 0;
1974 aEvent
.xclient
.data
.l
[4] = 0;
1975 XSendEvent( m_pDisplay
,
1976 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1978 SubstructureNotifyMask
| SubstructureRedirectMask
,
1983 setGnomeWMState( pFrame
);
1987 * WMAdaptor::showFullScreen
1989 void WMAdaptor::showFullScreen( X11SalFrame
* pFrame
, bool bFullScreen
) const
1991 pFrame
->mbFullScreen
= bFullScreen
;
1992 maximizeFrame( pFrame
, bFullScreen
, bFullScreen
);
1996 * NetWMAdaptor::showFullScreen
1998 void NetWMAdaptor::showFullScreen( X11SalFrame
* pFrame
, bool bFullScreen
) const
2000 if( m_aWMAtoms
[ NET_WM_STATE_FULLSCREEN
] )
2002 pFrame
->mbFullScreen
= bFullScreen
;
2005 if( m_aWMAtoms
[ MOTIF_WM_HINTS
] )
2007 XDeleteProperty( m_pDisplay
,
2008 pFrame
->GetShellWindow(),
2009 m_aWMAtoms
[ MOTIF_WM_HINTS
] );
2012 if( pFrame
->bMapped_
)
2014 // window already mapped, send WM a message
2016 aEvent
.type
= ClientMessage
;
2017 aEvent
.xclient
.display
= m_pDisplay
;
2018 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
2019 aEvent
.xclient
.message_type
= m_aWMAtoms
[ NET_WM_STATE
];
2020 aEvent
.xclient
.format
= 32;
2021 aEvent
.xclient
.data
.l
[0] = bFullScreen
? 1 : 0;
2022 aEvent
.xclient
.data
.l
[1] = m_aWMAtoms
[ NET_WM_STATE_FULLSCREEN
];
2023 aEvent
.xclient
.data
.l
[2] = 0;
2024 aEvent
.xclient
.data
.l
[3] = 0;
2025 aEvent
.xclient
.data
.l
[4] = 0;
2026 XSendEvent( m_pDisplay
,
2027 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
2029 SubstructureNotifyMask
| SubstructureRedirectMask
,
2035 // window not mapped yet, set _NET_WM_STATE directly
2036 setNetWMState( pFrame
);
2038 // #i42750# guess size before resize event shows up
2041 if( m_pSalDisplay
->IsXinerama() )
2043 ::Window aRoot
, aChild
;
2044 int root_x
= 0, root_y
= 0, lx
, ly
;
2046 XQueryPointer( m_pDisplay
,
2047 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
2049 &root_x
, &root_y
, &lx
, &ly
, &mask
);
2050 const std::vector
< tools::Rectangle
>& rScreens
= m_pSalDisplay
->GetXineramaScreens();
2051 Point
aMousePoint( root_x
, root_y
);
2052 for(const auto & rScreen
: rScreens
)
2054 if( rScreen
.IsInside( aMousePoint
) )
2056 pFrame
->maGeometry
.nX
= rScreen
.Left();
2057 pFrame
->maGeometry
.nY
= rScreen
.Top();
2058 pFrame
->maGeometry
.nWidth
= rScreen
.GetWidth();
2059 pFrame
->maGeometry
.nHeight
= rScreen
.GetHeight();
2066 Size aSize
= m_pSalDisplay
->GetScreenSize( pFrame
->GetScreenNumber() );
2067 pFrame
->maGeometry
.nX
= 0;
2068 pFrame
->maGeometry
.nY
= 0;
2069 pFrame
->maGeometry
.nWidth
= aSize
.Width();
2070 pFrame
->maGeometry
.nHeight
= aSize
.Height();
2072 pFrame
->CallCallback( SalEvent::MoveResize
, nullptr );
2075 else WMAdaptor::showFullScreen( pFrame
, bFullScreen
);
2079 * WMAdaptor::getCurrentWorkArea
2081 // FIXME: multiscreen case
2082 int WMAdaptor::getCurrentWorkArea() const
2085 if( m_aWMAtoms
[ NET_CURRENT_DESKTOP
] )
2087 Atom aRealType
= None
;
2089 unsigned long nItems
= 0;
2090 unsigned long nBytesLeft
= 0;
2091 unsigned char* pProperty
= nullptr;
2092 if( XGetWindowProperty( m_pDisplay
,
2093 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
2094 m_aWMAtoms
[ NET_CURRENT_DESKTOP
],
2106 nCurrent
= int(*reinterpret_cast<sal_Int32
*>(pProperty
));
2109 else if( pProperty
)
2112 pProperty
= nullptr;
2119 * WMAdaptor::getWindowWorkArea
2121 int WMAdaptor::getWindowWorkArea( ::Window aWindow
) const
2124 if( m_aWMAtoms
[ NET_WM_DESKTOP
] )
2126 Atom aRealType
= None
;
2128 unsigned long nItems
= 0;
2129 unsigned long nBytesLeft
= 0;
2130 unsigned char* pProperty
= nullptr;
2131 if( XGetWindowProperty( m_pDisplay
,
2133 m_aWMAtoms
[ NET_WM_DESKTOP
],
2145 nCurrent
= int(*reinterpret_cast<sal_Int32
*>(pProperty
));
2148 else if( pProperty
)
2151 pProperty
= nullptr;
2158 * WMAdaptor::getCurrentWorkArea
2160 // fixme: multi screen case
2161 void WMAdaptor::switchToWorkArea( int nWorkArea
) const
2163 if( ! getWMshouldSwitchWorkspace() )
2166 if( !m_aWMAtoms
[ NET_CURRENT_DESKTOP
] )
2170 aEvent
.type
= ClientMessage
;
2171 aEvent
.xclient
.display
= m_pDisplay
;
2172 aEvent
.xclient
.window
= m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() );
2173 aEvent
.xclient
.message_type
= m_aWMAtoms
[ NET_CURRENT_DESKTOP
];
2174 aEvent
.xclient
.format
= 32;
2175 aEvent
.xclient
.data
.l
[0] = nWorkArea
;
2176 aEvent
.xclient
.data
.l
[1] = 0;
2177 aEvent
.xclient
.data
.l
[2] = 0;
2178 aEvent
.xclient
.data
.l
[3] = 0;
2179 aEvent
.xclient
.data
.l
[4] = 0;
2180 XSendEvent( m_pDisplay
,
2181 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultXScreen() ),
2183 SubstructureNotifyMask
| SubstructureRedirectMask
,
2190 * WMAdaptor::frameIsMapping
2192 void WMAdaptor::frameIsMapping( X11SalFrame
* ) const
2197 * NetWMAdaptor::frameIsMapping
2199 void NetWMAdaptor::frameIsMapping( X11SalFrame
* pFrame
) const
2201 setNetWMState( pFrame
);
2205 * WMAdaptor::setUserTime
2207 void WMAdaptor::setUserTime( X11SalFrame
*, tools::Long
) const
2212 * NetWMAdaptor::setUserTime
2214 void NetWMAdaptor::setUserTime( X11SalFrame
* i_pFrame
, tools::Long i_nUserTime
) const
2216 if( m_aWMAtoms
[NET_WM_USER_TIME
] )
2218 XChangeProperty( m_pDisplay
,
2219 i_pFrame
->GetShellWindow(),
2220 m_aWMAtoms
[NET_WM_USER_TIME
],
2224 reinterpret_cast<unsigned char*>(&i_nUserTime
),
2233 void WMAdaptor::setPID( X11SalFrame
const * i_pFrame
) const
2235 if( !(m_aWMAtoms
[NET_WM_PID
]) )
2238 tools::Long nPID
= static_cast<tools::Long
>(getpid());
2239 XChangeProperty( m_pDisplay
,
2240 i_pFrame
->GetShellWindow(),
2241 m_aWMAtoms
[NET_WM_PID
],
2245 reinterpret_cast<unsigned char*>(&nPID
),
2251 * WMAdaptor::setClientMachine
2253 void WMAdaptor::setClientMachine( X11SalFrame
const * i_pFrame
) const
2255 OString
aWmClient( OUStringToOString( GetGenericUnixSalData()->GetHostname(), RTL_TEXTENCODING_ASCII_US
) );
2256 XTextProperty aClientProp
= { reinterpret_cast<unsigned char *>(const_cast<char *>(aWmClient
.getStr())), XA_STRING
, 8, sal::static_int_cast
<unsigned long>( aWmClient
.getLength() ) };
2257 XSetWMClientMachine( m_pDisplay
, i_pFrame
->GetShellWindow(), &aClientProp
);
2260 void WMAdaptor::answerPing( X11SalFrame
const * i_pFrame
, XClientMessageEvent
const * i_pEvent
) const
2262 if( !m_aWMAtoms
[NET_WM_PING
] ||
2263 i_pEvent
->message_type
!= m_aWMAtoms
[ WM_PROTOCOLS
] ||
2264 static_cast<Atom
>(i_pEvent
->data
.l
[0]) != m_aWMAtoms
[ NET_WM_PING
] )
2268 aEvent
.xclient
= *i_pEvent
;
2269 aEvent
.xclient
.window
= m_pSalDisplay
->GetRootWindow( i_pFrame
->GetScreenNumber() );
2270 XSendEvent( m_pDisplay
,
2271 m_pSalDisplay
->GetRootWindow( i_pFrame
->GetScreenNumber() ),
2273 SubstructureNotifyMask
| SubstructureRedirectMask
,
2276 XFlush( m_pDisplay
);
2279 void WMAdaptor::activateWindow( X11SalFrame
const *pFrame
, Time nTimestamp
)
2281 if (!pFrame
->bMapped_
)
2286 aEvent
.xclient
.type
= ClientMessage
;
2287 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
2288 aEvent
.xclient
.message_type
= m_aWMAtoms
[ NET_ACTIVE_WINDOW
];
2289 aEvent
.xclient
.format
= 32;
2290 aEvent
.xclient
.data
.l
[0] = 1;
2291 aEvent
.xclient
.data
.l
[1] = nTimestamp
;
2292 aEvent
.xclient
.data
.l
[2] = None
;
2293 aEvent
.xclient
.data
.l
[3] = 0;
2294 aEvent
.xclient
.data
.l
[4] = 0;
2296 XSendEvent( m_pDisplay
,
2297 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
2299 SubstructureNotifyMask
| SubstructureRedirectMask
,
2304 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */