1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: wmadaptor.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
37 #include <sal/alloca.h>
38 #include <wmadaptor.hxx>
39 #include <saldisp.hxx>
41 #include <vcl/salgdi.hxx>
42 #include <osl/thread.h>
43 #include <rtl/locale.h>
44 #include <osl/process.h>
46 #include <tools/prex.h>
48 #include <X11/Xatom.h>
49 #include <X11/Xresource.h>
50 #include <tools/postx.h>
52 #if OSL_DEBUG_LEVEL > 1
58 class NetWMAdaptor
: public WMAdaptor
60 void setNetWMState( X11SalFrame
* pFrame
) const;
62 virtual bool isValid() const;
64 NetWMAdaptor( SalDisplay
* );
65 virtual ~NetWMAdaptor();
67 virtual void setWMName( X11SalFrame
* pFrame
, const String
& rWMName
) const;
68 virtual void maximizeFrame( X11SalFrame
* pFrame
, bool bHorizontal
= true, bool bVertical
= true ) const;
69 virtual void shade( X11SalFrame
* pFrame
, bool bToShaded
) const;
70 virtual void setFrameTypeAndDecoration( X11SalFrame
* pFrame
, WMWindowType eType
, int nDecorationFlags
, X11SalFrame
* pTransientFrame
= NULL
) const;
71 virtual bool supportsICCCMPos() const;
72 virtual void enableAlwaysOnTop( X11SalFrame
* pFrame
, bool bEnable
) const;
73 virtual int handlePropertyNotify( X11SalFrame
* pFrame
, XPropertyEvent
* pEvent
) const;
74 virtual void showFullScreen( X11SalFrame
* pFrame
, bool bFullScreen
) const;
75 virtual void frameIsMapping( X11SalFrame
* pFrame
) const;
76 virtual void setFrameStruts( X11SalFrame
* pFrame
,
77 int left
, int right
, int top
, int bottom
,
78 int left_start_y
, int left_end_y
,
79 int right_start_y
, int right_end_y
,
80 int top_start_x
, int top_end_x
,
81 int bottom_start_x
, int bottom_end_x
) const;
82 virtual void setUserTime( X11SalFrame
* i_pFrame
, long i_nUserTime
) const;
85 class GnomeWMAdaptor
: public WMAdaptor
89 void setGnomeWMState( X11SalFrame
* pFrame
) const;
91 virtual bool isValid() const;
93 GnomeWMAdaptor( SalDisplay
* );
94 virtual ~GnomeWMAdaptor();
96 virtual void maximizeFrame( X11SalFrame
* pFrame
, bool bHorizontal
= true, bool bVertical
= true ) const;
97 virtual void shade( X11SalFrame
* pFrame
, bool bToShaded
) const;
98 virtual void enableAlwaysOnTop( X11SalFrame
* pFrame
, bool bEnable
) const;
99 virtual int handlePropertyNotify( X11SalFrame
* pFrame
, XPropertyEvent
* pEvent
) const;
104 using namespace vcl_sal
;
106 struct WMAdaptorProtocol
108 const char* pProtocol
;
114 * table must be sorted ascending in strings
115 * since it is use with bsearch
117 static const WMAdaptorProtocol aProtocolTab
[] =
119 { "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", WMAdaptor::KDE_NET_WM_WINDOW_TYPE_OVERRIDE
},
120 { "_NET_CURRENT_DESKTOP", WMAdaptor::NET_CURRENT_DESKTOP
},
121 { "_NET_NUMBER_OF_DESKTOPS", WMAdaptor::NET_NUMBER_OF_DESKTOPS
},
122 { "_NET_WM_DESKTOP", WMAdaptor::NET_WM_DESKTOP
},
123 { "_NET_WM_ICON_NAME", WMAdaptor::NET_WM_ICON_NAME
},
124 { "_NET_WM_STATE", WMAdaptor::NET_WM_STATE
},
125 { "_NET_WM_STATE_ABOVE", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP
},
126 { "_NET_WM_STATE_FULLSCREEN", WMAdaptor::NET_WM_STATE_FULLSCREEN
},
127 { "_NET_WM_STATE_MAXIMIZED_HORIZ", WMAdaptor::NET_WM_STATE_MAXIMIZED_HORZ
}, // common bug in e.g. older kwin and sawfish implementations
128 { "_NET_WM_STATE_MAXIMIZED_HORZ", WMAdaptor::NET_WM_STATE_MAXIMIZED_HORZ
},
129 { "_NET_WM_STATE_MAXIMIZED_VERT", WMAdaptor::NET_WM_STATE_MAXIMIZED_VERT
},
130 { "_NET_WM_STATE_MODAL", WMAdaptor::NET_WM_STATE_MODAL
},
131 { "_NET_WM_STATE_SHADED", WMAdaptor::NET_WM_STATE_SHADED
},
132 { "_NET_WM_STATE_SKIP_PAGER", WMAdaptor::NET_WM_STATE_SKIP_PAGER
},
133 { "_NET_WM_STATE_SKIP_TASKBAR", WMAdaptor::NET_WM_STATE_SKIP_TASKBAR
},
134 { "_NET_WM_STATE_STAYS_ON_TOP", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP
},
135 { "_NET_WM_STATE_STICKY", WMAdaptor::NET_WM_STATE_STICKY
},
136 { "_NET_WM_STRUT", WMAdaptor::NET_WM_STRUT
},
137 { "_NET_WM_STRUT_PARTIAL", WMAdaptor::NET_WM_STRUT_PARTIAL
},
138 { "_NET_WM_WINDOW_TYPE", WMAdaptor::NET_WM_WINDOW_TYPE
},
139 { "_NET_WM_WINDOW_TYPE_DESKTOP", WMAdaptor::NET_WM_WINDOW_TYPE_DESKTOP
},
140 { "_NET_WM_WINDOW_TYPE_DIALOG", WMAdaptor::NET_WM_WINDOW_TYPE_DIALOG
},
141 { "_NET_WM_WINDOW_TYPE_DOCK", WMAdaptor::NET_WM_WINDOW_TYPE_DOCK
},
142 { "_NET_WM_WINDOW_TYPE_MENU", WMAdaptor::NET_WM_WINDOW_TYPE_MENU
},
143 { "_NET_WM_WINDOW_TYPE_NORMAL", WMAdaptor::NET_WM_WINDOW_TYPE_NORMAL
},
144 { "_NET_WM_WINDOW_TYPE_SPLASH", WMAdaptor::NET_WM_WINDOW_TYPE_SPLASH
},
145 { "_NET_WM_WINDOW_TYPE_SPLASHSCREEN", WMAdaptor::NET_WM_WINDOW_TYPE_SPLASH
}, // bug in Metacity 2.4.1
146 { "_NET_WM_WINDOW_TYPE_TOOLBAR", WMAdaptor::NET_WM_WINDOW_TYPE_TOOLBAR
},
147 { "_NET_WM_WINDOW_TYPE_UTILITY", WMAdaptor::NET_WM_WINDOW_TYPE_UTILITY
},
148 { "_NET_WORKAREA", WMAdaptor::NET_WORKAREA
},
149 { "_WIN_APP_STATE", WMAdaptor::WIN_APP_STATE
},
150 { "_WIN_CLIENT_LIST", WMAdaptor::WIN_CLIENT_LIST
},
151 { "_WIN_EXPANDED_SIZE", WMAdaptor::WIN_EXPANDED_SIZE
},
152 { "_WIN_HINTS", WMAdaptor::WIN_HINTS
},
153 { "_WIN_ICONS", WMAdaptor::WIN_ICONS
},
154 { "_WIN_LAYER", WMAdaptor::WIN_LAYER
},
155 { "_WIN_STATE", WMAdaptor::WIN_STATE
},
156 { "_WIN_WORKSPACE", WMAdaptor::WIN_WORKSPACE
},
157 { "_WIN_WORKSPACE_COUNT", WMAdaptor::WIN_WORKSPACE_COUNT
}
161 * table containing atoms to get anyway
164 static const WMAdaptorProtocol aAtomTab
[] =
166 { "WM_STATE", WMAdaptor::WM_STATE
},
167 { "_MOTIF_WM_HINTS", WMAdaptor::MOTIF_WM_HINTS
},
168 { "WM_PROTOCOLS", WMAdaptor::WM_PROTOCOLS
},
169 { "WM_DELETE_WINDOW", WMAdaptor::WM_DELETE_WINDOW
},
170 { "WM_TAKE_FOCUS", WMAdaptor::WM_TAKE_FOCUS
},
171 { "WM_SAVE_YOURSELF", WMAdaptor::WM_SAVE_YOURSELF
},
172 { "WM_COMMAND", WMAdaptor::WM_COMMAND
},
173 { "WM_CLIENT_LEADER", WMAdaptor::WM_CLIENT_LEADER
},
174 { "WM_LOCALE_NAME", WMAdaptor::WM_LOCALE_NAME
},
175 { "WM_TRANSIENT_FOR", WMAdaptor::WM_TRANSIENT_FOR
},
176 { "SAL_QUITEVENT", WMAdaptor::SAL_QUITEVENT
},
177 { "SAL_USEREVENT", WMAdaptor::SAL_USEREVENT
},
178 { "SAL_EXTTEXTEVENT", WMAdaptor::SAL_EXTTEXTEVENT
},
179 { "SAL_GETTIMEEVENT", WMAdaptor::SAL_GETTIMEEVENT
},
180 { "VCL_SYSTEM_SETTINGS", WMAdaptor::VCL_SYSTEM_SETTINGS
},
181 { "DTWM_IS_RUNNING", WMAdaptor::DTWM_IS_RUNNING
},
182 { "_XSETTINGS_SETTINGS", WMAdaptor::XSETTINGS
},
183 { "_XEMBED", WMAdaptor::XEMBED
},
184 { "_XEMBED_INFO", WMAdaptor::XEMBED_INFO
},
185 { "_NET_WM_USER_TIME", WMAdaptor::NET_WM_USER_TIME
}
189 static int compareProtocol( const void* pLeft
, const void* pRight
)
191 return strcmp( ((const WMAdaptorProtocol
*)pLeft
)->pProtocol
, ((const WMAdaptorProtocol
*)pRight
)->pProtocol
);
195 WMAdaptor
* WMAdaptor::createWMAdaptor( SalDisplay
* pSalDisplay
)
197 WMAdaptor
* pAdaptor
= NULL
;
200 pAdaptor
= new NetWMAdaptor( pSalDisplay
);
201 if( ! pAdaptor
->isValid() )
202 delete pAdaptor
, pAdaptor
= NULL
;
203 #if OSL_DEBUG_LEVEL > 1
205 fprintf( stderr
, "WM supports extended WM hints\n" );
211 pAdaptor
= new GnomeWMAdaptor( pSalDisplay
);
212 if( ! pAdaptor
->isValid() )
213 delete pAdaptor
, pAdaptor
= NULL
;
214 #if OSL_DEBUG_LEVEL > 1
216 fprintf( stderr
, "WM supports GNOME WM hints\n" );
221 pAdaptor
= new WMAdaptor( pSalDisplay
);
223 #if OSL_DEBUG_LEVEL > 1
224 fprintf( stderr
, "Window Manager's name is \"%s\"\n",
225 ByteString( pAdaptor
->getWindowManagerName(), RTL_TEXTENCODING_ISO_8859_1
).GetBuffer() );
232 * WMAdaptor constructor
235 WMAdaptor::WMAdaptor( SalDisplay
* pDisplay
) :
236 m_pSalDisplay( pDisplay
),
237 m_bTransientBehaviour( true ),
238 m_bEnableAlwaysOnTopWorks( false ),
239 m_nWinGravity( StaticGravity
),
240 m_nInitWinGravity( StaticGravity
)
242 Atom aRealType
= None
;
244 unsigned long nItems
= 0;
245 unsigned long nBytesLeft
= 0;
246 unsigned char* pProperty
= NULL
;
250 m_aWMWorkAreas
= ::std::vector
< Rectangle
>
251 ( 1, Rectangle( Point(), m_pSalDisplay
->GetScreenSize( m_pSalDisplay
->GetDefaultScreenNumber() ) ) );
252 m_bEqualWorkAreas
= true;
254 memset( m_aWMAtoms
, 0, sizeof( m_aWMAtoms
) );
255 m_pDisplay
= m_pSalDisplay
->GetDisplay();
258 getNetWmName(); // try to discover e.g. Sawfish
260 // check for dtwm running
261 if( m_aWMAtoms
[ DTWM_IS_RUNNING
] )
263 if ( (XGetWindowProperty( m_pDisplay
,
264 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
265 m_aWMAtoms
[ DTWM_IS_RUNNING
],
275 || (XGetWindowProperty( m_pDisplay
,
276 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
277 m_aWMAtoms
[ DTWM_IS_RUNNING
],
280 m_aWMAtoms
[ DTWM_IS_RUNNING
],
290 m_aWMName
= String(RTL_CONSTASCII_USTRINGPARAM("Dtwm"));
291 m_bTransientBehaviour
= false;
292 m_nWinGravity
= CenterGravity
;
302 if( m_aWMName
.Len() == 0 )
304 // check for window maker - needs different gravity
305 Atom aWMakerRunning
= XInternAtom( m_pDisplay
, "_WINDOWMAKER_WM_PROTOCOLS", True
);
306 if( aWMakerRunning
!= None
&&
307 XGetWindowProperty( m_pDisplay
,
308 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
319 if( aRealType
== XA_ATOM
)
320 m_aWMName
= String( RTL_CONSTASCII_USTRINGPARAM("Windowmaker" ) );
322 m_nInitWinGravity
= NorthWestGravity
;
330 if( m_aWMName
.Len() == 0 )
332 if( XInternAtom( m_pDisplay
, "_OL_WIN_ATTR", True
) )
334 m_aWMName
= String( RTL_CONSTASCII_USTRINGPARAM( "Olwm" ) );
335 m_nInitWinGravity
= NorthWestGravity
;
338 if( m_aWMName
.Len() == 0 )
340 // check for ReflectionX wm (as it needs a workaround in Windows mode
341 Atom aRwmRunning
= XInternAtom( m_pDisplay
, "RWM_RUNNING", True
);
342 if( aRwmRunning
!= None
&&
343 XGetWindowProperty( m_pDisplay
,
344 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
355 if( aRealType
== aRwmRunning
)
356 m_aWMName
= String( RTL_CONSTASCII_USTRINGPARAM("ReflectionX" ) );
359 else if( (aRwmRunning
= XInternAtom( m_pDisplay
, "_WRQ_WM_RUNNING", True
)) != None
&&
360 XGetWindowProperty( m_pDisplay
,
361 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
372 if( aRealType
== XA_STRING
)
373 m_aWMName
= String( RTL_CONSTASCII_USTRINGPARAM( "ReflectionX Windows" ) );
377 if( m_aWMName
.Len() == 0 )
379 Atom aTTAPlatform
= XInternAtom( m_pDisplay
, "TTA_CLIENT_PLATFORM", True
);
380 if( aTTAPlatform
!= None
&&
381 XGetWindowProperty( m_pDisplay
,
382 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
393 if( aRealType
== XA_STRING
)
395 m_aWMName
= String( RTL_CONSTASCII_USTRINGPARAM("Tarantella" ) );
396 // #i62319# pretend that AlwaysOnTop works since
397 // the alwaysontop workaround in salframe.cxx results
398 // in a raise/lower loop on a Windows tarantella client
399 // FIXME: this property contains an identification string that
400 // in theory should be good enough to recognize running on a
401 // Windows client; however this string does not seem to be
402 // documented as well as the property itself.
403 m_bEnableAlwaysOnTopWorks
= true;
411 * WMAdaptor destructor
414 WMAdaptor::~WMAdaptor()
419 * NetWMAdaptor constructor
422 NetWMAdaptor::NetWMAdaptor( SalDisplay
* pSalDisplay
) :
423 WMAdaptor( pSalDisplay
)
425 // currently all _NET WMs do transient like expected
426 m_bTransientBehaviour
= true;
428 Atom aRealType
= None
;
430 unsigned long nItems
= 0;
431 unsigned long nBytesLeft
= 0;
432 unsigned char* pProperty
= NULL
;
438 bNetWM
= getNetWmName();
440 && XGetWindowProperty( m_pDisplay
,
441 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
442 m_aWMAtoms
[ NET_SUPPORTED
],
451 && aRealType
== XA_ATOM
460 // collect supported protocols
461 if( XGetWindowProperty( m_pDisplay
,
462 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
463 m_aWMAtoms
[ NET_SUPPORTED
],
475 Atom
* pAtoms
= (Atom
*)pProperty
;
476 char** pAtomNames
= (char**)alloca( sizeof(char*)*nItems
);
477 if( XGetAtomNames( m_pDisplay
, pAtoms
, nItems
, pAtomNames
) )
479 #if OSL_DEBUG_LEVEL > 1
480 fprintf( stderr
, "supported protocols:\n" );
482 for( unsigned int i
= 0; i
< nItems
; i
++ )
484 // #i80971# protect against invalid atoms
485 if( pAtomNames
[i
] == NULL
)
489 WMAdaptorProtocol aSearch
;
490 aSearch
.pProtocol
= pAtomNames
[i
];
491 WMAdaptorProtocol
* pMatch
= (WMAdaptorProtocol
*)
494 sizeof( aProtocolTab
)/sizeof( aProtocolTab
[0] ),
495 sizeof( struct WMAdaptorProtocol
),
499 nProtocol
= pMatch
->nProtocol
;
500 m_aWMAtoms
[ nProtocol
] = pAtoms
[ i
];
501 if( pMatch
->nProtocol
== NET_WM_STATE_STAYS_ON_TOP
)
502 m_bEnableAlwaysOnTopWorks
= true;
504 #if OSL_DEBUG_LEVEL > 1
505 fprintf( stderr
, " %s%s\n", pAtomNames
[i
], nProtocol
!= -1 ? "" : " (unsupported)" );
508 XFree( pAtomNames
[i
] );
520 // get number of desktops
521 if( m_aWMAtoms
[ NET_NUMBER_OF_DESKTOPS
]
522 && XGetWindowProperty( m_pDisplay
,
523 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
524 m_aWMAtoms
[ NET_NUMBER_OF_DESKTOPS
],
536 m_nDesktops
= *(long*)pProperty
;
540 if( m_aWMAtoms
[ NET_WORKAREA
]
541 && XGetWindowProperty( m_pDisplay
,
542 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
543 m_aWMAtoms
[ NET_WORKAREA
],
553 && nItems
== 4*(unsigned)m_nDesktops
556 m_aWMWorkAreas
= ::std::vector
< Rectangle
> ( m_nDesktops
);
557 long* pValues
= (long*)pProperty
;
558 for( int i
= 0; i
< m_nDesktops
; i
++ )
560 Point
aPoint( pValues
[4*i
],
562 Size
aSize( pValues
[4*i
+2],
564 Rectangle
aWorkArea( aPoint
, aSize
);
565 m_aWMWorkAreas
[i
] = aWorkArea
;
566 if( aWorkArea
!= m_aWMWorkAreas
[0] )
567 m_bEqualWorkAreas
= false;
568 #if OSL_DEBUG_LEVEL > 1
569 fprintf( stderr
, "workarea %d: %ldx%ld+%ld+%ld\n",
571 m_aWMWorkAreas
[i
].GetWidth(),
572 m_aWMWorkAreas
[i
].GetHeight(),
573 m_aWMWorkAreas
[i
].Left(),
574 m_aWMWorkAreas
[i
].Top() );
581 #if OSL_DEBUG_LEVEL > 1
582 fprintf( stderr
, "%ld workareas for %d desktops !\n", nItems
/4, m_nDesktops
);
605 * NetWMAdaptor destructor
607 NetWMAdaptor::~NetWMAdaptor()
612 * GnomeWMAdaptor constructor
615 GnomeWMAdaptor::GnomeWMAdaptor( SalDisplay
* pSalDisplay
) :
616 WMAdaptor( pSalDisplay
),
619 // currently all Gnome WMs do transient like expected
620 m_bTransientBehaviour
= true;
622 Atom aRealType
= None
;
624 unsigned long nItems
= 0;
625 unsigned long nBytesLeft
= 0;
626 unsigned char* pProperty
= NULL
;
631 if( m_aWMAtoms
[ WIN_SUPPORTING_WM_CHECK
] && m_aWMAtoms
[ WIN_PROTOCOLS
] )
633 XLIB_Window aWMChild
= None
;
634 if( XGetWindowProperty( m_pDisplay
,
635 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
636 m_aWMAtoms
[ WIN_SUPPORTING_WM_CHECK
],
645 && aRealType
== XA_CARDINAL
650 aWMChild
= *(XLIB_Window
*)pProperty
;
653 XLIB_Window aCheckWindow
= None
;
654 m_pSalDisplay
->GetXLib()->PushXErrorLevel( true );
655 if( XGetWindowProperty( m_pDisplay
,
657 m_aWMAtoms
[ WIN_SUPPORTING_WM_CHECK
],
666 && aRealType
== XA_CARDINAL
669 && ! m_pSalDisplay
->GetXLib()->HasXErrorOccured()
672 aCheckWindow
= *(XLIB_Window
*)pProperty
;
675 if( aCheckWindow
== aWMChild
)
680 * this is NOT part of the GNOME WM hints, but e.g. Sawfish
681 * already supports this part of the extended WM hints
683 m_aWMAtoms
[ UTF8_STRING
] = XInternAtom( m_pDisplay
, "UTF8_STRING", False
);
687 m_pSalDisplay
->GetXLib()->PopXErrorLevel();
696 && XGetWindowProperty( m_pDisplay
,
697 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
698 m_aWMAtoms
[ WIN_PROTOCOLS
],
707 && aRealType
== XA_ATOM
716 // collect supported protocols
717 if( XGetWindowProperty( m_pDisplay
,
718 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
719 m_aWMAtoms
[ WIN_PROTOCOLS
],
731 Atom
* pAtoms
= (Atom
*)pProperty
;
732 char** pAtomNames
= (char**)alloca( sizeof(char*)*nItems
);
733 if( XGetAtomNames( m_pDisplay
, pAtoms
, nItems
, pAtomNames
) )
735 #if OSL_DEBUG_LEVEL > 1
736 fprintf( stderr
, "supported protocols:\n" );
738 for( unsigned int i
= 0; i
< nItems
; i
++ )
740 // #i80971# protect against invalid atoms
741 if( pAtomNames
[i
] == NULL
)
745 WMAdaptorProtocol aSearch
;
746 aSearch
.pProtocol
= pAtomNames
[i
];
747 WMAdaptorProtocol
* pMatch
= (WMAdaptorProtocol
*)
750 sizeof( aProtocolTab
)/sizeof( aProtocolTab
[0] ),
751 sizeof( struct WMAdaptorProtocol
),
755 nProtocol
= pMatch
->nProtocol
;
756 m_aWMAtoms
[ nProtocol
] = pAtoms
[ i
];
757 if( pMatch
->nProtocol
== WIN_LAYER
)
758 m_bEnableAlwaysOnTopWorks
= true;
760 if( strncmp( "_ICEWM_TRAY", pAtomNames
[i
], 11 ) == 0 )
762 m_aWMName
= String(RTL_CONSTASCII_USTRINGPARAM("IceWM" ));
763 m_nWinGravity
= NorthWestGravity
;
764 m_nInitWinGravity
= NorthWestGravity
;
766 #if OSL_DEBUG_LEVEL > 1
767 fprintf( stderr
, " %s%s\n", pAtomNames
[i
], nProtocol
!= -1 ? "" : " (unsupported)" );
770 XFree( pAtomNames
[i
] );
782 // get number of desktops
783 if( m_aWMAtoms
[ WIN_WORKSPACE_COUNT
]
784 && XGetWindowProperty( m_pDisplay
,
785 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
786 m_aWMAtoms
[ WIN_WORKSPACE_COUNT
],
798 m_nDesktops
= *(long*)pProperty
;
816 * GnomeWMAdaptor destructor
818 GnomeWMAdaptor::~GnomeWMAdaptor()
825 bool WMAdaptor::getNetWmName()
827 Atom aRealType
= None
;
829 unsigned long nItems
= 0;
830 unsigned long nBytesLeft
= 0;
831 unsigned char* pProperty
= NULL
;
834 if( m_aWMAtoms
[ NET_SUPPORTING_WM_CHECK
] && m_aWMAtoms
[ NET_WM_NAME
] )
836 XLIB_Window aWMChild
= None
;
837 if( XGetWindowProperty( m_pDisplay
,
838 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
839 m_aWMAtoms
[ NET_SUPPORTING_WM_CHECK
],
848 && aRealType
== XA_WINDOW
853 aWMChild
= *(XLIB_Window
*)pProperty
;
856 XLIB_Window aCheckWindow
= None
;
857 m_pSalDisplay
->GetXLib()->PushXErrorLevel( true );
858 if( XGetWindowProperty( m_pDisplay
,
860 m_aWMAtoms
[ NET_SUPPORTING_WM_CHECK
],
869 && aRealType
== XA_WINDOW
872 && ! m_pSalDisplay
->GetXLib()->HasXErrorOccured()
875 aCheckWindow
= *(XLIB_Window
*)pProperty
;
878 if( aCheckWindow
== aWMChild
)
882 m_aWMAtoms
[ UTF8_STRING
] = XInternAtom( m_pDisplay
, "UTF8_STRING", False
);
883 if( XGetWindowProperty( m_pDisplay
,
885 m_aWMAtoms
[ NET_WM_NAME
],
888 AnyPropertyType
, /* m_aWMAtoms[ UTF8_STRING ],*/
897 if (aRealType
== m_aWMAtoms
[ UTF8_STRING
])
899 m_aWMName
= String( (sal_Char
*)pProperty
, nItems
, RTL_TEXTENCODING_UTF8
);
902 if (aRealType
== XA_STRING
)
904 m_aWMName
= String( (sal_Char
*)pProperty
, nItems
, RTL_TEXTENCODING_ISO_8859_1
);
922 m_pSalDisplay
->GetXLib()->PopXErrorLevel();
934 * WMAdaptor::isValid()
936 bool WMAdaptor::isValid() const
942 * NetWMAdaptor::isValid()
944 bool NetWMAdaptor::isValid() const
946 // some necessary sanity checks; there are WMs out there
947 // which implement some of the WM hints spec without
948 // real functionality
950 m_aWMAtoms
[ NET_SUPPORTED
]
951 && m_aWMAtoms
[ NET_SUPPORTING_WM_CHECK
]
952 && m_aWMAtoms
[ NET_WM_NAME
]
953 && m_aWMAtoms
[ NET_WM_WINDOW_TYPE_NORMAL
]
954 && m_aWMAtoms
[ NET_WM_WINDOW_TYPE_DIALOG
]
959 * GnomeWMAdaptor::isValid()
961 bool GnomeWMAdaptor::isValid() const
967 * WMAdaptor::initAtoms
970 void WMAdaptor::initAtoms()
973 for( unsigned int i
= 0; i
< sizeof( aAtomTab
)/sizeof( aAtomTab
[0] ); i
++ )
974 m_aWMAtoms
[ aAtomTab
[i
].nProtocol
] = XInternAtom( m_pDisplay
, aAtomTab
[i
].pProtocol
, False
);
975 m_aWMAtoms
[ NET_SUPPORTING_WM_CHECK
] = XInternAtom( m_pDisplay
, "_NET_SUPPORTING_WM_CHECK", True
);
976 m_aWMAtoms
[ NET_WM_NAME
] = XInternAtom( m_pDisplay
, "_NET_WM_NAME", True
);
980 * NetWMAdaptor::initAtoms
983 void NetWMAdaptor::initAtoms()
985 WMAdaptor::initAtoms();
987 m_aWMAtoms
[ NET_SUPPORTED
] = XInternAtom( m_pDisplay
, "_NET_SUPPORTED", True
);
991 * GnomeWMAdaptor::initAtoms
994 void GnomeWMAdaptor::initAtoms()
996 WMAdaptor::initAtoms();
998 m_aWMAtoms
[ WIN_PROTOCOLS
] = XInternAtom( m_pDisplay
, "_WIN_PROTOCOLS", True
);
999 m_aWMAtoms
[ WIN_SUPPORTING_WM_CHECK
] = XInternAtom( m_pDisplay
, "_WIN_SUPPORTING_WM_CHECK", True
);
1003 * WMAdaptor::setWMName
1008 void WMAdaptor::setWMName( X11SalFrame
* pFrame
, const String
& rWMName
) const
1010 ByteString
aTitle( rWMName
, osl_getThreadTextEncoding() );
1012 if( ! rWMName
.Len() && m_aWMName
.EqualsAscii( "Dtwm" ) )
1015 ::rtl::OString aWMLocale
;
1016 rtl_Locale
* pLocale
= NULL
;
1017 osl_getProcessLocale( &pLocale
);
1020 ::rtl::OUString
aLocaleString( pLocale
->Language
);
1021 ::rtl::OUString
aCountry( pLocale
->Country
);
1022 ::rtl::OUString
aVariant( pLocale
->Variant
);
1024 if( aCountry
.getLength() )
1026 aLocaleString
+= ::rtl::OUString::createFromAscii( "_" );
1027 aLocaleString
+= aCountry
;
1029 if( aVariant
.getLength() )
1030 aLocaleString
+= aVariant
;
1031 aWMLocale
= ::rtl::OUStringToOString( aLocaleString
, RTL_TEXTENCODING_ISO_8859_1
);
1035 static const char* pLang
= getenv( "LANG" );
1036 aWMLocale
= pLang
? pLang
: "C";
1039 static bool bTrustXmb
= true;
1041 /* #i64273# there are some weird cases when using IIIMP on Solaris
1042 * where for unknown reasons XmbTextListToTextProperty results in
1043 * garbage. Test one string once to ensure safety.
1045 * FIXME: This must be a bug in xiiimp.so.2 somewhere. However
1046 * it was not possible to recreate this in a small sample program.
1047 * This reeks of memory corruption somehow.
1049 static bool bOnce
= true;
1053 XTextProperty aTestProp
= { NULL
, None
, 0, 0 };
1054 const char *pText
= "trustme";
1055 XmbTextListToTextProperty( m_pDisplay
,
1056 &const_cast<char*>(pText
),
1060 bTrustXmb
= (aTestProp
.nitems
== 7) &&
1061 (aTestProp
.value
!= NULL
) &&
1062 (strncmp( (char*)aTestProp
.value
, pText
, 7 ) == 0) &&
1063 (aTestProp
.encoding
== XA_STRING
);
1064 if( aTestProp
.value
)
1065 XFree( aTestProp
.value
);
1066 #if OSL_DEBUG_LEVEL > 1
1067 fprintf( stderr
, "%s\n",
1069 "XmbTextListToTextProperty seems to work" :
1070 "XmbTextListToTextProperty does not seem to work" );
1075 char* pT
= const_cast<char*>(aTitle
.GetBuffer());
1076 XTextProperty aProp
= { NULL
, None
, 0, 0 };
1079 XmbTextListToTextProperty( m_pDisplay
,
1086 unsigned char* pData
= aProp
.nitems
? aProp
.value
: (unsigned char*)aTitle
.GetBuffer();
1087 Atom nType
= aProp
.nitems
? aProp
.encoding
: XA_STRING
;
1088 int nFormat
= aProp
.nitems
? aProp
.format
: 8;
1089 int nBytes
= aProp
.nitems
? aProp
.nitems
: aTitle
.Len();
1090 const SystemEnvData
* pEnv
= pFrame
->GetSystemData();
1091 XChangeProperty( m_pDisplay
,
1092 (XLIB_Window
)pEnv
->aShellWindow
,
1099 XChangeProperty( m_pDisplay
,
1100 (XLIB_Window
)pEnv
->aShellWindow
,
1107 XChangeProperty( m_pDisplay
,
1108 (XLIB_Window
)pEnv
->aShellWindow
,
1109 m_aWMAtoms
[ WM_LOCALE_NAME
],
1113 (unsigned char*)aWMLocale
.getStr(),
1114 aWMLocale
.getLength() );
1115 if (aProp
.value
!= NULL
)
1116 XFree( aProp
.value
);
1120 * NetWMAdaptor::setWMName
1126 void NetWMAdaptor::setWMName( X11SalFrame
* pFrame
, const String
& rWMName
) const
1128 WMAdaptor::setWMName( pFrame
, rWMName
);
1130 ByteString
aTitle( rWMName
, RTL_TEXTENCODING_UTF8
);
1131 const SystemEnvData
* pEnv
= pFrame
->GetSystemData();
1132 if( m_aWMAtoms
[ NET_WM_NAME
] )
1133 XChangeProperty( m_pDisplay
,
1134 (XLIB_Window
)pEnv
->aShellWindow
,
1135 m_aWMAtoms
[ NET_WM_NAME
],
1136 m_aWMAtoms
[ UTF8_STRING
],
1139 (unsigned char*)aTitle
.GetBuffer(),
1141 if( m_aWMAtoms
[ NET_WM_ICON_NAME
] )
1142 XChangeProperty( m_pDisplay
,
1143 (XLIB_Window
)pEnv
->aShellWindow
,
1144 m_aWMAtoms
[ NET_WM_ICON_NAME
],
1145 m_aWMAtoms
[ UTF8_STRING
],
1148 (unsigned char*)aTitle
.GetBuffer(),
1150 // The +1 copies the terminating null byte. Although
1151 // the spec says, this should not be necessary
1152 // at least the kwin implementation seems to depend
1157 * NetWMAdaptor::setNetWMState
1158 * sets _NET_WM_STATE
1160 void NetWMAdaptor::setNetWMState( X11SalFrame
* pFrame
) const
1162 if( m_aWMAtoms
[ NET_WM_STATE
] )
1164 Atom aStateAtoms
[ 10 ];
1165 int nStateAtoms
= 0;
1167 // set NET_WM_STATE_MODAL
1168 if( m_aWMAtoms
[ NET_WM_STATE_MODAL
]
1169 && pFrame
->meWindowType
== windowType_ModalDialogue
)
1171 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_MODAL
];
1173 * #90998# NET_WM_STATE_SKIP_TASKBAR set on a frame will
1174 * cause kwin not to give it the focus on map request
1175 * this seems to be a bug in kwin
1176 * aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_SKIP_TASKBAR ];
1179 if( pFrame
->mbMaximizedVert
1180 && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
] )
1181 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
];
1182 if( pFrame
->mbMaximizedHorz
1183 && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
] )
1184 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
];
1185 if( pFrame
->bAlwaysOnTop_
&& m_aWMAtoms
[ NET_WM_STATE_STAYS_ON_TOP
] )
1186 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_STAYS_ON_TOP
];
1187 if( pFrame
->mbShaded
&& m_aWMAtoms
[ NET_WM_STATE_SHADED
] )
1188 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_SHADED
];
1189 if( pFrame
->mbFullScreen
&& m_aWMAtoms
[ NET_WM_STATE_FULLSCREEN
] )
1190 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_FULLSCREEN
];
1191 if( pFrame
->meWindowType
== windowType_Utility
&& m_aWMAtoms
[ NET_WM_STATE_SKIP_TASKBAR
] )
1192 aStateAtoms
[ nStateAtoms
++ ] = m_aWMAtoms
[ NET_WM_STATE_SKIP_TASKBAR
];
1196 XChangeProperty( m_pDisplay
,
1197 pFrame
->GetShellWindow(),
1198 m_aWMAtoms
[ NET_WM_STATE
],
1202 (unsigned char*)aStateAtoms
,
1207 XDeleteProperty( m_pDisplay
,
1208 pFrame
->GetShellWindow(),
1209 m_aWMAtoms
[ NET_WM_STATE
] );
1210 if( pFrame
->mbMaximizedHorz
1211 && pFrame
->mbMaximizedVert
1212 && ! ( pFrame
->nStyle_
& SAL_FRAME_STYLE_SIZEABLE
) )
1215 * for maximizing use NorthWestGravity (including decoration)
1220 if( XGetWMNormalHints( m_pDisplay
,
1221 pFrame
->GetShellWindow(),
1226 hints
.flags
|= PWinGravity
;
1227 hints
.win_gravity
= NorthWestGravity
;
1228 XSetWMNormalHints( m_pDisplay
,
1229 pFrame
->GetShellWindow(),
1231 XSync( m_pDisplay
, False
);
1234 // SetPosSize necessary to set width/height, min/max w/h
1235 sal_Int32 nCurrent
= 0;
1237 * get current desktop here if work areas have different size
1238 * (does this happen on any platform ?)
1240 if( ! m_bEqualWorkAreas
)
1242 nCurrent
= getCurrentWorkArea();
1246 Rectangle aPosSize
= m_aWMWorkAreas
[nCurrent
];
1247 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
1248 aPosSize
= Rectangle( Point( aPosSize
.Left() + rGeom
.nLeftDecoration
,
1249 aPosSize
.Top() + rGeom
.nTopDecoration
),
1250 Size( aPosSize
.GetWidth()
1251 - rGeom
.nLeftDecoration
1252 - rGeom
.nRightDecoration
,
1253 aPosSize
.GetHeight()
1254 - rGeom
.nTopDecoration
1255 - rGeom
.nBottomDecoration
)
1257 pFrame
->SetPosSize( aPosSize
);
1260 * reset gravity hint to static gravity
1261 * (this should not move window according to ICCCM)
1263 if( bHint
&& pFrame
->nShowState_
!= SHOWSTATE_UNKNOWN
)
1265 hints
.win_gravity
= StaticGravity
;
1266 XSetWMNormalHints( m_pDisplay
,
1267 pFrame
->GetShellWindow(),
1275 * GnomeWMAdaptor::setNetWMState
1278 void GnomeWMAdaptor::setGnomeWMState( X11SalFrame
* pFrame
) const
1280 if( m_aWMAtoms
[ WIN_STATE
] )
1282 sal_uInt32 nWinWMState
= 0;
1284 if( pFrame
->mbMaximizedVert
)
1285 nWinWMState
|= 1 << 2;
1286 if( pFrame
->mbMaximizedHorz
)
1287 nWinWMState
|= 1 << 3;
1288 if( pFrame
->mbShaded
)
1289 nWinWMState
|= 1 << 5;
1291 XChangeProperty( m_pDisplay
,
1292 pFrame
->GetShellWindow(),
1293 m_aWMAtoms
[ WIN_STATE
],
1297 (unsigned char*)&nWinWMState
,
1300 if( pFrame
->mbMaximizedHorz
1301 && pFrame
->mbMaximizedVert
1302 && ! ( pFrame
->nStyle_
& SAL_FRAME_STYLE_SIZEABLE
) )
1305 * for maximizing use NorthWestGravity (including decoration)
1310 if( XGetWMNormalHints( m_pDisplay
,
1311 pFrame
->GetShellWindow(),
1316 hints
.flags
|= PWinGravity
;
1317 hints
.win_gravity
= NorthWestGravity
;
1318 XSetWMNormalHints( m_pDisplay
,
1319 pFrame
->GetShellWindow(),
1321 XSync( m_pDisplay
, False
);
1324 // SetPosSize necessary to set width/height, min/max w/h
1325 sal_Int32 nCurrent
= 0;
1327 * get current desktop here if work areas have different size
1328 * (does this happen on any platform ?)
1330 if( ! m_bEqualWorkAreas
)
1332 nCurrent
= getCurrentWorkArea();
1336 Rectangle aPosSize
= m_aWMWorkAreas
[nCurrent
];
1337 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
1338 aPosSize
= Rectangle( Point( aPosSize
.Left() + rGeom
.nLeftDecoration
,
1339 aPosSize
.Top() + rGeom
.nTopDecoration
),
1340 Size( aPosSize
.GetWidth()
1341 - rGeom
.nLeftDecoration
1342 - rGeom
.nRightDecoration
,
1343 aPosSize
.GetHeight()
1344 - rGeom
.nTopDecoration
1345 - rGeom
.nBottomDecoration
)
1347 pFrame
->SetPosSize( aPosSize
);
1350 * reset gravity hint to static gravity
1351 * (this should not move window according to ICCCM)
1353 if( bHint
&& pFrame
->nShowState_
!= SHOWSTATE_UNKNOWN
)
1355 hints
.win_gravity
= StaticGravity
;
1356 XSetWMNormalHints( m_pDisplay
,
1357 pFrame
->GetShellWindow(),
1365 * WMAdaptor::setFrameDecoration
1366 * sets _MOTIF_WM_HINTS
1370 void WMAdaptor::setFrameTypeAndDecoration( X11SalFrame
* pFrame
, WMWindowType eType
, int nDecorationFlags
, X11SalFrame
* pReferenceFrame
) const
1372 pFrame
->meWindowType
= eType
;
1373 pFrame
->mnDecorationFlags
= nDecorationFlags
;
1377 unsigned long flags
, func
, deco
;
1379 unsigned long status
;
1382 aHint
.flags
= 15; /* flags for functions, decoration, input mode and status */
1384 aHint
.func
= 1L << 2;
1386 aHint
.input_mode
= 0;
1388 // evaluate decoration flags
1389 if( nDecorationFlags
& decoration_All
)
1390 aHint
.deco
= 1, aHint
.func
= 1;
1393 if( nDecorationFlags
& decoration_Title
)
1394 aHint
.deco
|= 1L << 3;
1395 if( nDecorationFlags
& decoration_Border
)
1396 aHint
.deco
|= 1L << 1;
1397 if( nDecorationFlags
& decoration_Resize
)
1398 aHint
.deco
|= 1L << 2, aHint
.func
|= 1L << 1;
1399 if( nDecorationFlags
& decoration_MinimizeBtn
)
1400 aHint
.deco
|= 1L << 5, aHint
.func
|= 1L << 3;
1401 if( nDecorationFlags
& decoration_MaximizeBtn
)
1402 aHint
.deco
|= 1L << 6, aHint
.func
|= 1L << 4;
1403 if( nDecorationFlags
& decoration_CloseBtn
)
1404 aHint
.deco
|= 1L << 4, aHint
.func
|= 1L << 5;
1406 // evaluate window type
1409 case windowType_ModalDialogue
:
1410 aHint
.input_mode
= 1;
1417 XChangeProperty( m_pDisplay
,
1418 pFrame
->GetShellWindow(),
1419 m_aWMAtoms
[ MOTIF_WM_HINTS
],
1420 m_aWMAtoms
[ MOTIF_WM_HINTS
],
1423 (unsigned char*)&aHint
,
1426 // set transientFor hint
1427 /* #91030# dtwm will not map a dialogue if the transient
1428 * window is iconified. This is deemed undesireable because
1429 * message boxes do not get mapped, so use the root as transient
1432 if( pReferenceFrame
)
1434 XSetTransientForHint( m_pDisplay
,
1435 pFrame
->GetShellWindow(),
1436 pReferenceFrame
->bMapped_
?
1437 pReferenceFrame
->GetShellWindow() :
1438 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() )
1440 if( ! pReferenceFrame
->bMapped_
)
1441 pFrame
->mbTransientForRoot
= true;
1443 // #110333# in case no one ever sets a title prevent
1444 // the Dtwm taking the class instead
1445 if( m_aWMName
.EqualsAscii( "Dtwm" ) )
1446 setWMName( pFrame
, String() );
1450 * NetWMAdaptor::setFrameDecoration
1451 * sets _MOTIF_WM_HINTS
1452 * _NET_WM_WINDOW_TYPE
1457 void NetWMAdaptor::setFrameTypeAndDecoration( X11SalFrame
* pFrame
, WMWindowType eType
, int nDecorationFlags
, X11SalFrame
* pReferenceFrame
) const
1459 WMAdaptor::setFrameTypeAndDecoration( pFrame
, eType
, nDecorationFlags
, pReferenceFrame
);
1461 setNetWMState( pFrame
);
1463 // set NET_WM_WINDOW_TYPE
1464 if( m_aWMAtoms
[ NET_WM_WINDOW_TYPE
] )
1466 Atom aWindowTypes
[4];
1467 int nWindowTypes
= 0;
1470 case windowType_Utility
:
1471 aWindowTypes
[nWindowTypes
++] =
1472 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_UTILITY
] ?
1473 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_UTILITY
] :
1474 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_DIALOG
];
1476 case windowType_ModelessDialogue
:
1477 case windowType_ModalDialogue
:
1478 aWindowTypes
[nWindowTypes
++] =
1479 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_DIALOG
];
1481 case windowType_Splash
:
1482 aWindowTypes
[nWindowTypes
++] =
1483 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_SPLASH
] ?
1484 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_SPLASH
] :
1485 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_NORMAL
];
1487 case windowType_Toolbar
:
1488 if( m_aWMAtoms
[ KDE_NET_WM_WINDOW_TYPE_OVERRIDE
] )
1489 aWindowTypes
[nWindowTypes
++] = m_aWMAtoms
[ KDE_NET_WM_WINDOW_TYPE_OVERRIDE
];
1490 aWindowTypes
[nWindowTypes
++] =
1491 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_TOOLBAR
] ?
1492 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_TOOLBAR
] :
1493 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_NORMAL
];
1495 case windowType_Dock
:
1496 aWindowTypes
[nWindowTypes
++] =
1497 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_DOCK
] ?
1498 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_DOCK
] :
1499 m_aWMAtoms
[ NET_WM_WINDOW_TYPE_NORMAL
];
1502 aWindowTypes
[nWindowTypes
++] = m_aWMAtoms
[ NET_WM_WINDOW_TYPE_NORMAL
];
1505 XChangeProperty( m_pDisplay
,
1506 pFrame
->GetShellWindow(),
1507 m_aWMAtoms
[ NET_WM_WINDOW_TYPE
],
1511 (unsigned char*)aWindowTypes
,
1514 if( ( eType
== windowType_ModalDialogue
||
1515 eType
== windowType_ModelessDialogue
)
1516 && ! pReferenceFrame
)
1518 XSetTransientForHint( m_pDisplay
,
1519 pFrame
->GetShellWindow(),
1520 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ) );
1521 pFrame
->mbTransientForRoot
= true;
1526 * WMAdaptor::maximizeFrame
1529 void WMAdaptor::maximizeFrame( X11SalFrame
* pFrame
, bool bHorizontal
, bool bVertical
) const
1531 pFrame
->mbMaximizedVert
= bVertical
;
1532 pFrame
->mbMaximizedHorz
= bHorizontal
;
1534 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
1536 // discard pending configure notifies for this frame
1537 XSync( m_pDisplay
, False
);
1539 while( XCheckTypedWindowEvent( m_pDisplay
,
1540 pFrame
->GetShellWindow(),
1544 while( XCheckTypedWindowEvent( m_pDisplay
,
1545 pFrame
->GetWindow(),
1550 if( bHorizontal
|| bVertical
)
1552 Size
aScreenSize( m_pSalDisplay
->GetScreenSize( pFrame
->GetScreenNumber() ) );
1553 Point
aTL( rGeom
.nLeftDecoration
, rGeom
.nTopDecoration
);
1554 if( m_pSalDisplay
->IsXinerama() )
1556 Point
aMed( aTL
.X() + rGeom
.nWidth
/2, aTL
.Y() + rGeom
.nHeight
/2 );
1557 const std::vector
< Rectangle
>& rScreens
= m_pSalDisplay
->GetXineramaScreens();
1558 for( unsigned int i
= 0; i
< rScreens
.size(); i
++ )
1559 if( rScreens
[i
].IsInside( aMed
) )
1561 aTL
+= rScreens
[i
].TopLeft();
1562 aScreenSize
= rScreens
[i
].GetSize();
1566 Rectangle
aTarget( aTL
,
1567 Size( aScreenSize
.Width() - rGeom
.nLeftDecoration
- rGeom
.nTopDecoration
,
1568 aScreenSize
.Height() - rGeom
.nTopDecoration
- rGeom
.nBottomDecoration
)
1574 pFrame
->maRestorePosSize
.IsEmpty() ?
1575 rGeom
.nWidth
: pFrame
->maRestorePosSize
.GetWidth(),
1580 pFrame
->maRestorePosSize
.IsEmpty() ?
1581 rGeom
.nX
: pFrame
->maRestorePosSize
.Left();
1583 else if( ! bVertical
)
1588 pFrame
->maRestorePosSize
.IsEmpty() ?
1589 rGeom
.nHeight
: pFrame
->maRestorePosSize
.GetHeight()
1593 pFrame
->maRestorePosSize
.IsEmpty() ?
1594 rGeom
.nY
: pFrame
->maRestorePosSize
.Top();
1597 Rectangle
aRestore( Point( rGeom
.nX
, rGeom
.nY
), Size( rGeom
.nWidth
, rGeom
.nHeight
) );
1598 if( pFrame
->bMapped_
)
1600 XSetInputFocus( m_pDisplay
,
1601 pFrame
->GetShellWindow(),
1605 if( m_aWMName
.EqualsAscii( "Dtwm" ) )
1608 * Dtwm will only position correctly with center gravity
1609 * and in this case the request actually changes the frame
1610 * not the shell window
1612 aTarget
= Rectangle( Point( 0, 0 ), aScreenSize
);
1613 aRestore
.Move( -rGeom
.nLeftDecoration
, -rGeom
.nTopDecoration
);
1617 if( pFrame
->maRestorePosSize
.IsEmpty() )
1618 pFrame
->maRestorePosSize
= aRestore
;
1620 pFrame
->SetPosSize( aTarget
);
1621 pFrame
->nWidth_
= aTarget
.GetWidth();
1622 pFrame
->nHeight_
= aTarget
.GetHeight();
1623 XRaiseWindow( m_pDisplay
,
1624 pFrame
->GetShellWindow()
1626 if( pFrame
->GetStackingWindow() )
1627 XRaiseWindow( m_pDisplay
,
1628 pFrame
->GetStackingWindow()
1634 pFrame
->SetPosSize( pFrame
->maRestorePosSize
);
1635 pFrame
->maRestorePosSize
= Rectangle();
1636 pFrame
->nWidth_
= rGeom
.nWidth
;
1637 pFrame
->nHeight_
= rGeom
.nHeight
;
1638 if( m_aWMName
.EqualsAscii( "Dtwm" ) && pFrame
->bMapped_
)
1640 pFrame
->maGeometry
.nX
+= rGeom
.nLeftDecoration
;
1641 pFrame
->maGeometry
.nY
+= rGeom
.nTopDecoration
;
1647 * NetWMAdaptor::maximizeFrame
1648 * changes _NET_WM_STATE by sending a client message
1651 void NetWMAdaptor::maximizeFrame( X11SalFrame
* pFrame
, bool bHorizontal
, bool bVertical
) const
1653 pFrame
->mbMaximizedVert
= bVertical
;
1654 pFrame
->mbMaximizedHorz
= bHorizontal
;
1656 if( m_aWMAtoms
[ NET_WM_STATE
]
1657 && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
]
1658 && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
]
1659 && ( pFrame
->nStyle_
& ~SAL_FRAME_STYLE_DEFAULT
)
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] = bHorizontal
? 1 : 0;
1672 aEvent
.xclient
.data
.l
[1] = m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
];
1673 aEvent
.xclient
.data
.l
[2] = bHorizontal
== bVertical
? m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
] : 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
,
1682 if( bHorizontal
!= bVertical
)
1684 aEvent
.xclient
.data
.l
[0]= bVertical
? 1 : 0;
1685 aEvent
.xclient
.data
.l
[1]= m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
];
1686 aEvent
.xclient
.data
.l
[2]= 0;
1687 XSendEvent( m_pDisplay
,
1688 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1690 SubstructureNotifyMask
| SubstructureRedirectMask
,
1697 // window not mapped yet, set _NET_WM_STATE directly
1698 setNetWMState( pFrame
);
1700 if( !bHorizontal
&& !bVertical
)
1701 pFrame
->maRestorePosSize
= Rectangle();
1702 else if( pFrame
->maRestorePosSize
.IsEmpty() )
1704 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
1705 pFrame
->maRestorePosSize
=
1706 Rectangle( Point( rGeom
.nX
, rGeom
.nY
), Size( rGeom
.nWidth
, rGeom
.nHeight
) );
1710 WMAdaptor::maximizeFrame( pFrame
, bHorizontal
, bVertical
);
1714 * GnomeWMAdaptor::maximizeFrame
1715 * changes _WIN_STATE by sending a client message
1718 void GnomeWMAdaptor::maximizeFrame( X11SalFrame
* pFrame
, bool bHorizontal
, bool bVertical
) const
1720 pFrame
->mbMaximizedVert
= bVertical
;
1721 pFrame
->mbMaximizedHorz
= bHorizontal
;
1723 if( m_aWMAtoms
[ WIN_STATE
]
1724 && ( pFrame
->nStyle_
& ~SAL_FRAME_STYLE_DEFAULT
)
1727 if( pFrame
->bMapped_
)
1729 // window already mapped, send WM a message
1731 aEvent
.type
= ClientMessage
;
1732 aEvent
.xclient
.display
= m_pDisplay
;
1733 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
1734 aEvent
.xclient
.message_type
= m_aWMAtoms
[ WIN_STATE
];
1735 aEvent
.xclient
.format
= 32;
1736 aEvent
.xclient
.data
.l
[0] = (1<<2)|(1<<3);
1737 aEvent
.xclient
.data
.l
[1] =
1738 (bVertical
? (1<<2) : 0)
1739 | (bHorizontal
? (1<<3) : 0);
1740 aEvent
.xclient
.data
.l
[2] = 0;
1741 aEvent
.xclient
.data
.l
[3] = 0;
1742 aEvent
.xclient
.data
.l
[4] = 0;
1743 XSendEvent( m_pDisplay
,
1744 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1746 SubstructureNotifyMask
,
1751 // window not mapped yet, set _WIN_STATE directly
1752 setGnomeWMState( pFrame
);
1754 if( !bHorizontal
&& !bVertical
)
1755 pFrame
->maRestorePosSize
= Rectangle();
1756 else if( pFrame
->maRestorePosSize
.IsEmpty() )
1758 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
1759 pFrame
->maRestorePosSize
=
1760 Rectangle( Point( rGeom
.nX
, rGeom
.nY
), Size( rGeom
.nWidth
, rGeom
.nHeight
) );
1764 WMAdaptor::maximizeFrame( pFrame
, bHorizontal
, bVertical
);
1768 * WMAdaptor::supportsICCCMPos
1771 bool WMAdaptor::supportsICCCMPos() const
1774 m_aWMName
.EqualsAscii( "Sawfish" )
1775 || m_aWMName
.EqualsAscii( "Dtwm" );
1779 * NetWMAdaptor::supportsICCCMPos
1782 bool NetWMAdaptor::supportsICCCMPos() const
1789 * WMAdaptor::enableAlwaysOnTop
1791 void WMAdaptor::enableAlwaysOnTop( X11SalFrame
*, bool /*bEnable*/ ) const
1796 * NetWMAdaptor::enableAlwaysOnTop
1798 void NetWMAdaptor::enableAlwaysOnTop( X11SalFrame
* pFrame
, bool bEnable
) const
1800 pFrame
->bAlwaysOnTop_
= bEnable
;
1801 if( m_aWMAtoms
[ NET_WM_STATE_STAYS_ON_TOP
] )
1803 if( pFrame
->bMapped_
)
1805 // window already mapped, send WM a message
1807 aEvent
.type
= ClientMessage
;
1808 aEvent
.xclient
.display
= m_pDisplay
;
1809 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
1810 aEvent
.xclient
.message_type
= m_aWMAtoms
[ NET_WM_STATE
];
1811 aEvent
.xclient
.format
= 32;
1812 aEvent
.xclient
.data
.l
[0] = bEnable
? 1 : 0;
1813 aEvent
.xclient
.data
.l
[1] = m_aWMAtoms
[ NET_WM_STATE_STAYS_ON_TOP
];
1814 aEvent
.xclient
.data
.l
[2] = 0;
1815 aEvent
.xclient
.data
.l
[3] = 0;
1816 aEvent
.xclient
.data
.l
[4] = 0;
1817 XSendEvent( m_pDisplay
,
1818 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1820 SubstructureNotifyMask
| SubstructureRedirectMask
,
1825 setNetWMState( pFrame
);
1830 * GnomeWMAdaptor::enableAlwaysOnTop
1832 void GnomeWMAdaptor::enableAlwaysOnTop( X11SalFrame
* pFrame
, bool bEnable
) const
1834 pFrame
->bAlwaysOnTop_
= bEnable
;
1835 if( m_aWMAtoms
[ WIN_LAYER
] )
1837 if( pFrame
->bMapped_
)
1839 // window already mapped, send WM a message
1841 aEvent
.type
= ClientMessage
;
1842 aEvent
.xclient
.display
= m_pDisplay
;
1843 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
1844 aEvent
.xclient
.message_type
= m_aWMAtoms
[ WIN_LAYER
];
1845 aEvent
.xclient
.format
= 32;
1846 aEvent
.xclient
.data
.l
[0] = bEnable
? 6 : 4;
1847 aEvent
.xclient
.data
.l
[1] = 0;
1848 aEvent
.xclient
.data
.l
[2] = 0;
1849 aEvent
.xclient
.data
.l
[3] = 0;
1850 aEvent
.xclient
.data
.l
[4] = 0;
1851 XSendEvent( m_pDisplay
,
1852 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
1854 SubstructureNotifyMask
| SubstructureRedirectMask
,
1860 sal_uInt32 nNewLayer
= bEnable
? 6 : 4;
1861 XChangeProperty( m_pDisplay
,
1862 pFrame
->GetShellWindow(),
1863 m_aWMAtoms
[ WIN_LAYER
],
1867 (unsigned char*)&nNewLayer
,
1875 * WMAdaptor::changeReferenceFrame
1877 void WMAdaptor::changeReferenceFrame( X11SalFrame
* pFrame
, X11SalFrame
* pReferenceFrame
) const
1879 if( ! ( pFrame
->nStyle_
& SAL_FRAME_STYLE_PLUG
)
1880 && ! pFrame
->IsOverrideRedirect()
1881 && ! pFrame
->IsFloatGrabWindow()
1884 XLIB_Window aTransient
= pFrame
->pDisplay_
->GetRootWindow( pFrame
->GetScreenNumber() );
1885 pFrame
->mbTransientForRoot
= true;
1886 if( pReferenceFrame
)
1888 aTransient
= pReferenceFrame
->GetShellWindow();
1889 pFrame
->mbTransientForRoot
= false;
1891 XSetTransientForHint( m_pDisplay
,
1892 pFrame
->GetShellWindow(),
1898 * WMAdaptor::handlePropertyNotify
1900 int WMAdaptor::handlePropertyNotify( X11SalFrame
*, XPropertyEvent
* ) const
1906 * NetWMAdaptor::handlePropertyNotify
1908 int NetWMAdaptor::handlePropertyNotify( X11SalFrame
* pFrame
, XPropertyEvent
* pEvent
) const
1911 if( pEvent
->atom
== m_aWMAtoms
[ NET_WM_STATE
] )
1913 pFrame
->mbMaximizedHorz
= pFrame
->mbMaximizedVert
= false;
1914 pFrame
->mbShaded
= false;
1916 if( pEvent
->state
== PropertyNewValue
)
1918 Atom nType
, *pStates
;
1920 unsigned long nItems
, nBytesLeft
;
1921 unsigned char* pData
= NULL
;
1925 XGetWindowProperty( m_pDisplay
,
1927 m_aWMAtoms
[ NET_WM_STATE
],
1933 &nItems
, &nBytesLeft
,
1937 if( nType
== XA_ATOM
&& nFormat
== 32 && nItems
> 0 )
1939 pStates
= (Atom
*)pData
;
1940 for( unsigned long i
= 0; i
< nItems
; i
++ )
1942 if( pStates
[i
] == m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
] && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_VERT
] )
1943 pFrame
->mbMaximizedVert
= true;
1944 else if( pStates
[i
] == m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
] && m_aWMAtoms
[ NET_WM_STATE_MAXIMIZED_HORZ
] )
1945 pFrame
->mbMaximizedHorz
= true;
1946 else if( pStates
[i
] == m_aWMAtoms
[ NET_WM_STATE_SHADED
] && m_aWMAtoms
[ NET_WM_STATE_SHADED
] )
1947 pFrame
->mbShaded
= true;
1952 nOffset
+= nItems
* nFormat
/ 32;
1956 } while( nBytesLeft
> 0 );
1959 if( ! (pFrame
->mbMaximizedHorz
|| pFrame
->mbMaximizedVert
) )
1960 pFrame
->maRestorePosSize
= Rectangle();
1963 const SalFrameGeometry
& rGeom
= pFrame
->GetUnmirroredGeometry();
1964 // the current geometry may already be changed by the corresponding
1965 // ConfigureNotify, but this cannot be helped
1966 pFrame
->maRestorePosSize
=
1967 Rectangle( Point( rGeom
.nX
, rGeom
.nY
),
1968 Size( rGeom
.nWidth
, rGeom
.nHeight
) );
1971 else if( pEvent
->atom
== m_aWMAtoms
[ NET_WM_DESKTOP
] )
1973 pFrame
->m_nWorkArea
= getWindowWorkArea( pFrame
->GetShellWindow() );
1982 * GnomeWMAdaptor::handlePropertyNotify
1984 int GnomeWMAdaptor::handlePropertyNotify( X11SalFrame
* pFrame
, XPropertyEvent
* pEvent
) const
1987 if( pEvent
->atom
== m_aWMAtoms
[ WIN_STATE
] )
1989 pFrame
->mbMaximizedHorz
= pFrame
->mbMaximizedVert
= false;
1990 pFrame
->mbShaded
= false;
1992 if( pEvent
->state
== PropertyNewValue
)
1996 unsigned long nItems
= 0;
1997 unsigned long nBytesLeft
= 0;
1998 unsigned char* pData
= 0;
1999 XGetWindowProperty( m_pDisplay
,
2001 m_aWMAtoms
[ WIN_STATE
],
2007 &nItems
, &nBytesLeft
,
2011 if( nType
== XA_CARDINAL
&& nFormat
== 32 && nItems
== 1 )
2013 sal_uInt32 nWinState
= *(sal_uInt32
*)pData
;
2014 if( nWinState
& (1<<2) )
2015 pFrame
->mbMaximizedVert
= true;
2016 if( nWinState
& (1<<3) )
2017 pFrame
->mbMaximizedHorz
= true;
2018 if( nWinState
& (1<<5) )
2019 pFrame
->mbShaded
= true;
2025 if( ! (pFrame
->mbMaximizedHorz
|| pFrame
->mbMaximizedVert
) )
2026 pFrame
->maRestorePosSize
= Rectangle();
2029 const SalFrameGeometry
& rGeom
= pFrame
->GetUnmirroredGeometry();
2030 // the current geometry may already be changed by the corresponding
2031 // ConfigureNotify, but this cannot be helped
2032 pFrame
->maRestorePosSize
=
2033 Rectangle( Point( rGeom
.nX
, rGeom
.nY
),
2034 Size( rGeom
.nWidth
, rGeom
.nHeight
) );
2037 else if( pEvent
->atom
== m_aWMAtoms
[ NET_WM_DESKTOP
] )
2039 pFrame
->m_nWorkArea
= getWindowWorkArea( pFrame
->GetShellWindow() );
2050 void WMAdaptor::shade( X11SalFrame
*, bool /*bToShaded*/ ) const
2055 * NetWMAdaptor::shade
2057 void NetWMAdaptor::shade( X11SalFrame
* pFrame
, bool bToShaded
) const
2059 if( m_aWMAtoms
[ NET_WM_STATE
]
2060 && m_aWMAtoms
[ NET_WM_STATE_SHADED
]
2061 && ( pFrame
->nStyle_
& ~SAL_FRAME_STYLE_DEFAULT
)
2064 pFrame
->mbShaded
= bToShaded
;
2065 if( pFrame
->bMapped_
)
2067 // window already mapped, send WM a message
2069 aEvent
.type
= ClientMessage
;
2070 aEvent
.xclient
.display
= m_pDisplay
;
2071 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
2072 aEvent
.xclient
.message_type
= m_aWMAtoms
[ NET_WM_STATE
];
2073 aEvent
.xclient
.format
= 32;
2074 aEvent
.xclient
.data
.l
[0] = bToShaded
? 1 : 0;
2075 aEvent
.xclient
.data
.l
[1] = m_aWMAtoms
[ NET_WM_STATE_SHADED
];
2076 aEvent
.xclient
.data
.l
[2] = 0;
2077 aEvent
.xclient
.data
.l
[3] = 0;
2078 aEvent
.xclient
.data
.l
[4] = 0;
2079 XSendEvent( m_pDisplay
,
2080 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
2082 SubstructureNotifyMask
| SubstructureRedirectMask
,
2088 // window not mapped yet, set _NET_WM_STATE directly
2089 setNetWMState( pFrame
);
2095 * GnomeWMAdaptor::shade
2097 void GnomeWMAdaptor::shade( X11SalFrame
* pFrame
, bool bToShaded
) const
2099 if( m_aWMAtoms
[ WIN_STATE
] )
2101 pFrame
->mbShaded
= bToShaded
;
2102 if( pFrame
->bMapped_
)
2104 // window already mapped, send WM a message
2106 aEvent
.type
= ClientMessage
;
2107 aEvent
.xclient
.display
= m_pDisplay
;
2108 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
2109 aEvent
.xclient
.message_type
= m_aWMAtoms
[ WIN_STATE
];
2110 aEvent
.xclient
.format
= 32;
2111 aEvent
.xclient
.data
.l
[0] = (1<<5);
2112 aEvent
.xclient
.data
.l
[1] = bToShaded
? (1<<5) : 0;
2113 aEvent
.xclient
.data
.l
[2] = 0;
2114 aEvent
.xclient
.data
.l
[3] = 0;
2115 aEvent
.xclient
.data
.l
[4] = 0;
2116 XSendEvent( m_pDisplay
,
2117 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
2119 SubstructureNotifyMask
| SubstructureRedirectMask
,
2124 setGnomeWMState( pFrame
);
2129 * WMAdaptor::showFullScreen
2131 void WMAdaptor::showFullScreen( X11SalFrame
* pFrame
, bool bFullScreen
) const
2133 pFrame
->mbFullScreen
= bFullScreen
;
2134 maximizeFrame( pFrame
, bFullScreen
, bFullScreen
);
2138 * NetWMAdaptor::showFullScreen
2140 void NetWMAdaptor::showFullScreen( X11SalFrame
* pFrame
, bool bFullScreen
) const
2142 if( m_aWMAtoms
[ NET_WM_STATE_FULLSCREEN
] )
2144 pFrame
->mbFullScreen
= bFullScreen
;
2145 if( pFrame
->bMapped_
)
2147 // window already mapped, send WM a message
2149 aEvent
.type
= ClientMessage
;
2150 aEvent
.xclient
.display
= m_pDisplay
;
2151 aEvent
.xclient
.window
= pFrame
->GetShellWindow();
2152 aEvent
.xclient
.message_type
= m_aWMAtoms
[ NET_WM_STATE
];
2153 aEvent
.xclient
.format
= 32;
2154 aEvent
.xclient
.data
.l
[0] = bFullScreen
? 1 : 0;
2155 aEvent
.xclient
.data
.l
[1] = m_aWMAtoms
[ NET_WM_STATE_FULLSCREEN
];
2156 aEvent
.xclient
.data
.l
[2] = 0;
2157 aEvent
.xclient
.data
.l
[3] = 0;
2158 aEvent
.xclient
.data
.l
[4] = 0;
2159 XSendEvent( m_pDisplay
,
2160 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
2162 SubstructureNotifyMask
| SubstructureRedirectMask
,
2168 // window not mapped yet, set _NET_WM_STATE directly
2169 setNetWMState( pFrame
);
2171 // #i42750# guess size before resize event shows up
2174 if( m_pSalDisplay
->IsXinerama() )
2176 XLIB_Window aRoot
, aChild
;
2177 int root_x
= 0, root_y
= 0, lx
, ly
;
2179 XQueryPointer( m_pDisplay
,
2180 m_pSalDisplay
->GetRootWindow( pFrame
->GetScreenNumber() ),
2182 &root_x
, &root_y
, &lx
, &ly
, &mask
);
2183 const std::vector
< Rectangle
>& rScreens
= m_pSalDisplay
->GetXineramaScreens();
2184 Point
aMousePoint( root_x
, root_y
);
2185 for( unsigned int i
= 0; i
< rScreens
.size(); i
++ )
2187 if( rScreens
[i
].IsInside( aMousePoint
) )
2189 pFrame
->maGeometry
.nX
= rScreens
[i
].Left();
2190 pFrame
->maGeometry
.nY
= rScreens
[i
].Top();
2191 pFrame
->maGeometry
.nWidth
= rScreens
[i
].GetWidth();
2192 pFrame
->maGeometry
.nHeight
= rScreens
[i
].GetHeight();
2199 Size aSize
= m_pSalDisplay
->GetScreenSize( pFrame
->GetScreenNumber() );
2200 pFrame
->maGeometry
.nX
= 0;
2201 pFrame
->maGeometry
.nY
= 0;
2202 pFrame
->maGeometry
.nWidth
= aSize
.Width();
2203 pFrame
->maGeometry
.nHeight
= aSize
.Height();
2205 pFrame
->CallCallback( SALEVENT_MOVERESIZE
, NULL
);
2208 else WMAdaptor::showFullScreen( pFrame
, bFullScreen
);
2212 * WMAdaptor::getCurrentWorkArea
2214 // FIXME: multiscreen case
2215 int WMAdaptor::getCurrentWorkArea() const
2218 if( m_aWMAtoms
[ NET_CURRENT_DESKTOP
] )
2220 Atom aRealType
= None
;
2222 unsigned long nItems
= 0;
2223 unsigned long nBytesLeft
= 0;
2224 unsigned char* pProperty
= NULL
;
2225 if( XGetWindowProperty( m_pDisplay
,
2226 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
2227 m_aWMAtoms
[ NET_CURRENT_DESKTOP
],
2239 nCurrent
= int(*(sal_Int32
*)pProperty
);
2242 else if( pProperty
)
2252 * WMAdaptor::getWindowWorkArea
2254 int WMAdaptor::getWindowWorkArea( XLIB_Window aWindow
) const
2257 if( m_aWMAtoms
[ NET_WM_DESKTOP
] )
2259 Atom aRealType
= None
;
2261 unsigned long nItems
= 0;
2262 unsigned long nBytesLeft
= 0;
2263 unsigned char* pProperty
= NULL
;
2264 if( XGetWindowProperty( m_pDisplay
,
2266 m_aWMAtoms
[ NET_WM_DESKTOP
],
2278 nCurrent
= int(*(sal_Int32
*)pProperty
);
2281 else if( pProperty
)
2291 * WMAdaptor::getCurrentWorkArea
2293 // fixme: multi screen case
2294 void WMAdaptor::switchToWorkArea( int nWorkArea
) const
2296 if( m_aWMAtoms
[ NET_CURRENT_DESKTOP
] )
2299 aEvent
.type
= ClientMessage
;
2300 aEvent
.xclient
.display
= m_pDisplay
;
2301 aEvent
.xclient
.window
= m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() );
2302 aEvent
.xclient
.message_type
= m_aWMAtoms
[ NET_CURRENT_DESKTOP
];
2303 aEvent
.xclient
.format
= 32;
2304 aEvent
.xclient
.data
.l
[0] = nWorkArea
;
2305 aEvent
.xclient
.data
.l
[1] = 0;
2306 aEvent
.xclient
.data
.l
[2] = 0;
2307 aEvent
.xclient
.data
.l
[3] = 0;
2308 aEvent
.xclient
.data
.l
[4] = 0;
2309 XSendEvent( m_pDisplay
,
2310 m_pSalDisplay
->GetRootWindow( m_pSalDisplay
->GetDefaultScreenNumber() ),
2312 SubstructureNotifyMask
| SubstructureRedirectMask
,
2319 * WMAdaptor::frameIsMapping
2321 void WMAdaptor::frameIsMapping( X11SalFrame
* ) const
2326 * NetWMAdaptor::frameIsMapping
2328 void NetWMAdaptor::frameIsMapping( X11SalFrame
* pFrame
) const
2330 setNetWMState( pFrame
);
2334 * WMAdaptor::setFrameStruts
2336 void WMAdaptor::setFrameStruts( X11SalFrame
*,
2339 int, int, int, int ) const
2344 * NetWMAdaptor::setFrameStruts
2346 void NetWMAdaptor::setFrameStruts( X11SalFrame
* pFrame
,
2347 int left
, int right
, int top
, int bottom
,
2348 int left_start_y
, int left_end_y
,
2349 int right_start_y
, int right_end_y
,
2350 int top_start_x
, int top_end_x
,
2351 int bottom_start_x
, int bottom_end_x
) const
2358 nData
[4] = left_start_y
;
2359 nData
[5] = left_end_y
;
2360 nData
[6] = right_start_y
;
2361 nData
[7] = right_end_y
;
2362 nData
[8] = top_start_x
;
2363 nData
[9] = top_end_x
;
2364 nData
[10]= bottom_start_x
;
2365 nData
[11]= bottom_end_x
;
2366 Atom aProperty
= None
;
2369 if( m_aWMAtoms
[NET_WM_STRUT_PARTIAL
] )
2371 aProperty
= m_aWMAtoms
[NET_WM_STRUT_PARTIAL
];
2374 else if( m_aWMAtoms
[NET_WM_STRUT
] )
2376 aProperty
= m_aWMAtoms
[NET_WM_STRUT
];
2381 XChangeProperty( m_pDisplay
,
2382 pFrame
->GetShellWindow(),
2387 (unsigned char*)&nData
,
2394 * WMAdaptor::setUserTime
2396 void WMAdaptor::setUserTime( X11SalFrame
*, long ) const
2401 * NetWMAdaptor::setUserTime
2403 void NetWMAdaptor::setUserTime( X11SalFrame
* i_pFrame
, long i_nUserTime
) const
2405 if( m_aWMAtoms
[NET_WM_USER_TIME
] )
2407 XChangeProperty( m_pDisplay
,
2408 i_pFrame
->GetShellWindow(),
2409 m_aWMAtoms
[NET_WM_USER_TIME
],
2413 (unsigned char*)&i_nUserTime
,