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: salframe.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"
39 #include <tools/prex.h>
40 #include <X11/Xatom.h>
41 #include <X11/keysym.h>
43 #include <X11/extensions/shape.h>
45 #include <X11/extensions/dpms.h>
47 #include <tools/postx.h>
50 #include "saldata.hxx"
51 #include "saldisp.hxx"
57 #include "wmadaptor.hxx"
60 #include "i18n_ic.hxx"
61 #include "i18n_keysym.hxx"
62 #include "i18n_status.hxx"
64 #include "vcl/salinst.hxx"
65 #include "vcl/floatwin.hxx"
66 #include "vcl/sallayout.hxx"
67 #include "vcl/svapp.hxx"
68 #include "vcl/keycodes.hxx"
69 #include "vcl/printerinfomanager.hxx"
70 #include "vcl/settings.hxx"
72 #include "tools/debug.hxx"
74 #include "sal/alloca.h"
75 #include <com/sun/star/uno/Exception.hpp>
86 using namespace vcl_sal
;
89 // -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
90 #define CLIENT_EVENTS StructureNotifyMask \
91 | SubstructureNotifyMask \
101 | VisibilityChangeMask \
102 | PropertyChangeMask \
105 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
107 static XLIB_Window hPresentationWindow
= None
, hPresFocusWindow
= None
;
108 static ::std::list
< XLIB_Window
> aPresentationReparentList
;
109 static int nVisibleFloats
= 0;
111 X11SalFrame
* X11SalFrame::s_pSaveYourselfFrame
= NULL
;
113 // -=-= C++ statics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
114 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
115 static void doReparentPresentationDialogues( SalDisplay
* pDisplay
)
117 pDisplay
->GetXLib()->PushXErrorLevel( true );
118 while( aPresentationReparentList
.begin() != aPresentationReparentList
.end() )
121 XLIB_Window aRoot
, aChild
;
122 unsigned int w
, h
, bw
, d
;
123 XGetGeometry( pDisplay
->GetDisplay(),
124 aPresentationReparentList
.front(),
126 &x
, &y
, &w
, &h
, &bw
, &d
);
127 XTranslateCoordinates( pDisplay
->GetDisplay(),
133 XReparentWindow( pDisplay
->GetDisplay(),
134 aPresentationReparentList
.front(),
137 aPresentationReparentList
.pop_front();
139 if( hPresFocusWindow
)
140 XSetInputFocus( pDisplay
->GetDisplay(), hPresFocusWindow
, PointerRoot
, CurrentTime
);
141 XSync( pDisplay
->GetDisplay(), False
);
142 pDisplay
->GetXLib()->PopXErrorLevel();
145 // -=-= SalFrame / X11SalFrame =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
146 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
148 bool X11SalFrame::IsOverrideRedirect() const
151 ((nStyle_
& SAL_FRAME_STYLE_INTRO
) && !pDisplay_
->getWMAdaptor()->supportsSplash())
153 (!( nStyle_
& ~SAL_FRAME_STYLE_DEFAULT
) && !pDisplay_
->getWMAdaptor()->supportsFullScreen())
157 bool X11SalFrame::IsFloatGrabWindow() const
159 static const char* pDisableGrab
= getenv( "SAL_DISABLE_FLOATGRAB" );
162 ( ( !pDisableGrab
|| !*pDisableGrab
) &&
164 (nStyle_
& SAL_FRAME_STYLE_FLOAT
) &&
165 ! (nStyle_
& SAL_FRAME_STYLE_TOOLTIP
) &&
166 ! (nStyle_
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
)
171 void X11SalFrame::setXEmbedInfo()
176 aInfo
[0] = 1; // XEMBED protocol version
177 aInfo
[1] = (bMapped_
? 1 : 0); // XEMBED_MAPPED
178 XChangeProperty( pDisplay_
->GetDisplay(),
180 pDisplay_
->getWMAdaptor()->getAtom( WMAdaptor::XEMBED_INFO
),
181 pDisplay_
->getWMAdaptor()->getAtom( WMAdaptor::XEMBED_INFO
),
184 reinterpret_cast<unsigned char*>(aInfo
),
185 sizeof(aInfo
)/sizeof(aInfo
[0]) );
189 void X11SalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode
)
193 rtl_zeroMemory( &aEvent
, sizeof(aEvent
) );
194 aEvent
.xclient
.window
= mhForeignParent
;
195 aEvent
.xclient
.type
= ClientMessage
;
196 aEvent
.xclient
.message_type
= pDisplay_
->getWMAdaptor()->getAtom( WMAdaptor::XEMBED
);
197 aEvent
.xclient
.format
= 32;
198 aEvent
.xclient
.data
.l
[0] = i_nTimeCode
? i_nTimeCode
: CurrentTime
;
199 aEvent
.xclient
.data
.l
[1] = 3; // XEMBED_REQUEST_FOCUS
200 aEvent
.xclient
.data
.l
[2] = 0;
201 aEvent
.xclient
.data
.l
[3] = 0;
202 aEvent
.xclient
.data
.l
[4] = 0;
204 GetDisplay()->GetXLib()->PushXErrorLevel( true );
205 XSendEvent( pDisplay_
->GetDisplay(),
207 False
, NoEventMask
, &aEvent
);
208 XSync( pDisplay_
->GetDisplay(), False
);
209 GetDisplay()->GetXLib()->PopXErrorLevel();
213 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
215 void X11SalFrame::Init( ULONG nSalFrameStyle
, int nScreen
, SystemParentData
* pParentData
, bool bUseGeometry
)
217 if( nScreen
< 0 || nScreen
>= GetDisplay()->GetScreenCount() )
218 nScreen
= GetDisplay()->GetDefaultScreenNumber();
220 nScreen
= mpParent
->m_nScreen
;
223 nStyle_
= nSalFrameStyle
;
225 Hints
.flags
= InputHint
;
226 Hints
.input
= (nSalFrameStyle
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) ? False
: True
;
229 unsigned int w
= 500, h
= 500;
230 XSetWindowAttributes Attributes
;
232 int nAttrMask
= CWBorderPixel
238 Attributes
.border_pixel
= 0;
239 Attributes
.background_pixmap
= None
;
240 Attributes
.colormap
= GetDisplay()->GetColormap( m_nScreen
).GetXColormap();
241 Attributes
.override_redirect
= False
;
242 Attributes
.event_mask
= CLIENT_EVENTS
;
244 const SalVisual
& rVis
= GetDisplay()->GetVisual( m_nScreen
);
245 XLIB_Window aFrameParent
= pParentData
? pParentData
->aWindow
: GetDisplay()->GetRootWindow( m_nScreen
);
246 XLIB_Window aClientLeader
= None
;
252 w
= maGeometry
.nWidth
;
253 h
= maGeometry
.nHeight
;
256 if( (nSalFrameStyle
& SAL_FRAME_STYLE_FLOAT
) &&
257 ! (nSalFrameStyle
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
)
260 if( nShowState_
== SHOWSTATE_UNKNOWN
)
265 Attributes
.override_redirect
= True
;
267 else if( (nSalFrameStyle
& SAL_FRAME_STYLE_SYSTEMCHILD
) )
269 DBG_ASSERT( mpParent
, "SAL_FRAME_STYLE_SYSTEMCHILD window without parent" );
272 aFrameParent
= mpParent
->mhWindow
;
273 // FIXME: since with SAL_FRAME_STYLE_SYSTEMCHILD
274 // multiple X11SalFrame objects can have the same shell window
275 // dispatching events in saldisp.cxx is unclear (the first frame)
276 // wins. HTH this correctly is unclear yet
277 // for the time being, treat set the shell window to own window
278 // like for a normal frame
279 // mhShellWindow = mpParent->GetShellWindow();
282 else if( pParentData
)
284 // plugin parent may be killed unexpectedly by
285 // plugging process; ignore XErrors in that case
286 GetDisplay()->setHaveSystemChildFrame();
288 nStyle_
|= SAL_FRAME_STYLE_PLUG
;
289 Attributes
.override_redirect
= True
;
290 if( pParentData
->nSize
>= sizeof(SystemParentData
) )
291 m_bXEmbed
= pParentData
->bXEmbedSupport
;
295 XLIB_Window aRoot
, aParent
;
297 XGetGeometry( GetXDisplay(), pParentData
->aWindow
,
298 &aRoot
, &x_ret
, &y_ret
, &w
, &h
, &bw
, &d
);
299 mhForeignParent
= pParentData
->aWindow
;
301 mhShellWindow
= aParent
= mhForeignParent
;
302 XLIB_Window
* pChildren
;
303 unsigned int nChildren
;
307 XQueryTree( GetDisplay()->GetDisplay(), mhShellWindow
,
308 &aRoot
, &aParent
, &pChildren
, &nChildren
);
310 if( aParent
!= aRoot
)
311 mhShellWindow
= aParent
;
313 Atom
* pProps
= XListProperties( GetDisplay()->GetDisplay(),
316 for( int i
= 0; i
< nCount
&& ! bBreak
; ++i
)
317 bBreak
= (pProps
[i
] == XA_WM_HINTS
);
320 } while( aParent
!= aRoot
&& ! bBreak
);
322 // check if this is really one of our own frames
323 // do not change the input mask in that case
324 const std::list
< SalFrame
* >& rFrames
= GetDisplay()->getFrames();
325 std::list
< SalFrame
* >::const_iterator it
= rFrames
.begin();
326 while( it
!= rFrames
.end() && mhForeignParent
!= static_cast<const X11SalFrame
*>(*it
)->GetWindow() )
329 if( it
== rFrames
.end() )
331 XSelectInput( GetDisplay()->GetDisplay(), mhForeignParent
, StructureNotifyMask
| FocusChangeMask
);
332 XSelectInput( GetDisplay()->GetDisplay(), mhShellWindow
, StructureNotifyMask
| FocusChangeMask
);
339 Size
aScreenSize( GetDisplay()->getDataForScreen( m_nScreen
).m_aSize
);
340 w
= aScreenSize
.Width();
341 h
= aScreenSize
.Height();
342 if( nSalFrameStyle
& SAL_FRAME_STYLE_SIZEABLE
&&
343 nSalFrameStyle
& SAL_FRAME_STYLE_MOVEABLE
)
345 // fill in holy default values brought to us by product management
346 if( aScreenSize
.Width() >= 800 )
348 if( aScreenSize
.Width() >= 1024 )
351 if( aScreenSize
.Height() >= 600 )
353 if( aScreenSize
.Height() >= 768 )
355 if( aScreenSize
.Height() >= 1024 )
360 // find the last document window (if any)
361 const X11SalFrame
* pFrame
= NULL
;
362 const std::list
< SalFrame
* >& rFrames
= GetDisplay()->getFrames();
363 std::list
< SalFrame
* >::const_iterator it
= rFrames
.begin();
364 while( it
!= rFrames
.end() )
366 pFrame
= static_cast< const X11SalFrame
* >(*it
);
367 if( ! ( pFrame
->mpParent
368 || pFrame
->mbFullScreen
369 || ! ( pFrame
->nStyle_
& SAL_FRAME_STYLE_SIZEABLE
)
370 || ! pFrame
->GetUnmirroredGeometry().nWidth
371 || ! pFrame
->GetUnmirroredGeometry().nHeight
378 if( it
!= rFrames
.end() )
380 // set a document position and size
381 // the first frame gets positioned by the window manager
382 const SalFrameGeometry
& rGeom( pFrame
->GetUnmirroredGeometry() );
385 if( x
+(int)w
+40 <= (int)aScreenSize
.Width() &&
386 y
+(int)h
+40 <= (int)aScreenSize
.Height()
394 x
= 10; // leave some space for decoration
398 else if( GetDisplay()->IsXinerama() )
400 // place frame on same screen as mouse pointer
401 XLIB_Window aRoot
, aChild
;
402 int root_x
= 0, root_y
= 0, lx
, ly
;
404 XQueryPointer( GetXDisplay(),
405 GetDisplay()->GetRootWindow( m_nScreen
),
407 &root_x
, &root_y
, &lx
, &ly
, &mask
);
408 const std::vector
< Rectangle
>& rScreens
= GetDisplay()->GetXineramaScreens();
409 for( unsigned int i
= 0; i
< rScreens
.size(); i
++ )
410 if( rScreens
[i
].IsInside( Point( root_x
, root_y
) ) )
412 x
= rScreens
[i
].Left();
413 y
= rScreens
[i
].Top();
419 Attributes
.win_gravity
= pDisplay_
->getWMAdaptor()->getInitWinGravity();
420 nAttrMask
|= CWWinGravity
;
423 Attributes
.save_under
= True
;
424 nAttrMask
|= CWSaveUnder
;
426 if( IsOverrideRedirect() )
427 Attributes
.override_redirect
= True
;
429 if( (nStyle_
& SAL_FRAME_STYLE_INTRO
) == 0 )
434 bOk
=SelectAppIconPixmap( pDisplay_
, m_nScreen
,
435 mnIconID
!= 1 ? mnIconID
:
436 (mpParent
? mpParent
->mnIconID
: 1), 32,
437 Hints
.icon_pixmap
, Hints
.icon_mask
);
439 catch( com::sun::star::uno::Exception
& )
441 // can happen - no ucb during early startup
445 Hints
.flags
|= IconPixmapHint
;
446 if( Hints
.icon_mask
)
447 Hints
.flags
|= IconMaskHint
;
451 // find the top level frame of the transience hierarchy
452 X11SalFrame
* pFrame
= this;
453 while( pFrame
->mpParent
)
454 pFrame
= pFrame
->mpParent
;
455 if( (pFrame
->nStyle_
& SAL_FRAME_STYLE_PLUG
) )
457 // if the top level window is a plugin window,
458 // then we should place us in the same window group as
459 // the parent application (or none if there is no window group
460 // hint in the parent).
461 if( pFrame
->GetShellWindow() )
463 XWMHints
* pWMHints
= XGetWMHints( pDisplay_
->GetDisplay(),
464 pFrame
->GetShellWindow() );
467 if( (pWMHints
->flags
& WindowGroupHint
) )
469 Hints
.flags
|= WindowGroupHint
;
470 Hints
.window_group
= pWMHints
->window_group
;
478 Hints
.flags
|= WindowGroupHint
;
479 Hints
.window_group
= pFrame
->GetShellWindow();
480 // note: for a normal document window this will produce None
481 // as the window is not yet created and the shell window is
482 // initialized to None. This must be corrected after window creation.
483 aClientLeader
= GetDisplay()->GetDrawable( m_nScreen
);
487 nShowState_
= SHOWSTATE_UNKNOWN
;
490 nVisibility_
= VisibilityFullyObscured
;
491 mhWindow
= XCreateWindow( GetXDisplay(),
501 // FIXME: see above: fake shell window for now to own window
502 if( /*! IsSysChildWindow() &&*/ pParentData
== NULL
)
504 mhShellWindow
= mhWindow
;
507 // correct window group if necessary
508 if( (Hints
.flags
& WindowGroupHint
) == WindowGroupHint
)
510 if( Hints
.window_group
== None
)
511 Hints
.window_group
= GetShellWindow();
516 maGeometry
.nWidth
= w
;
517 maGeometry
.nHeight
= h
;
518 updateScreenNumber();
520 XSync( GetXDisplay(), False
);
523 XLIB_Time nUserTime
= (nStyle_
& (SAL_FRAME_STYLE_OWNERDRAWDECORATION
| SAL_FRAME_STYLE_TOOLWINDOW
) ) == 0 ?
524 pDisplay_
->GetLastUserEventTime() : 0;
525 pDisplay_
->getWMAdaptor()->setUserTime( this, nUserTime
);
527 if( ! pParentData
&& ! IsChildWindow() && ! Attributes
.override_redirect
)
529 XSetWMHints( GetXDisplay(), mhWindow
, &Hints
);
530 // WM Protocols && internals
533 a
[n
++] = pDisplay_
->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW
);
534 if( ! s_pSaveYourselfFrame
&& ! mpParent
)
536 // at all times have only one frame with SaveYourself
537 a
[n
++] = pDisplay_
->getWMAdaptor()->getAtom( WMAdaptor::WM_SAVE_YOURSELF
);
538 s_pSaveYourselfFrame
= this;
540 if( (nSalFrameStyle
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) )
541 a
[n
++] = pDisplay_
->getWMAdaptor()->getAtom( WMAdaptor::WM_TAKE_FOCUS
);
542 XSetWMProtocols( GetXDisplay(), GetShellWindow(), a
, n
);
544 XClassHint
* pClass
= XAllocClassHint();
545 pClass
->res_name
= const_cast<char*>(X11SalData::getFrameResName());
546 pClass
->res_class
= const_cast<char*>(X11SalData::getFrameClassName());
547 XSetClassHint( GetXDisplay(), GetShellWindow(), pClass
);
550 XSizeHints
* pHints
= XAllocSizeHints();
551 pHints
->flags
= PWinGravity
| PPosition
;
552 pHints
->win_gravity
= GetDisplay()->getWMAdaptor()->getPositionWinGravity();
555 XSetWMNormalHints( GetXDisplay(),
563 XChangeProperty( GetXDisplay(),
565 pDisplay_
->getWMAdaptor()->getAtom( WMAdaptor::WM_CLIENT_LEADER
),
569 (unsigned char*)&aClientLeader
,
573 #define DECOFLAGS (SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE)
574 int nDecoFlags
= WMAdaptor::decoration_All
;
575 if( (nStyle_
& SAL_FRAME_STYLE_PARTIAL_FULLSCREEN
) ||
576 (nStyle_
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
)
579 else if( (nStyle_
& DECOFLAGS
) != DECOFLAGS
|| (nStyle_
& SAL_FRAME_STYLE_TOOLWINDOW
) )
581 if( nStyle_
& DECOFLAGS
)
582 // if any decoration, then show a border
583 nDecoFlags
= WMAdaptor::decoration_Border
;
587 if( ! mpParent
&& (nStyle_
& DECOFLAGS
) )
588 // don't add a min button if window should be decorationless
589 nDecoFlags
|= WMAdaptor::decoration_MinimizeBtn
;
590 if( nStyle_
& SAL_FRAME_STYLE_CLOSEABLE
)
591 nDecoFlags
|= WMAdaptor::decoration_CloseBtn
;
592 if( nStyle_
& SAL_FRAME_STYLE_SIZEABLE
)
594 nDecoFlags
|= WMAdaptor::decoration_Resize
;
595 if( ! (nStyle_
& SAL_FRAME_STYLE_TOOLWINDOW
) )
596 nDecoFlags
|= WMAdaptor::decoration_MaximizeBtn
;
598 if( nStyle_
& SAL_FRAME_STYLE_MOVEABLE
)
599 nDecoFlags
|= WMAdaptor::decoration_Title
;
602 WMAdaptor::WMWindowType eType
= WMAdaptor::windowType_Normal
;
603 if( nStyle_
& SAL_FRAME_STYLE_INTRO
)
604 eType
= WMAdaptor::windowType_Splash
;
605 if( (nStyle_
& SAL_FRAME_STYLE_DIALOG
) && hPresentationWindow
== None
)
606 eType
= WMAdaptor::windowType_ModelessDialogue
;
607 if( nStyle_
& SAL_FRAME_STYLE_TOOLWINDOW
)
608 eType
= WMAdaptor::windowType_Utility
;
609 if( nStyle_
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
)
610 eType
= WMAdaptor::windowType_Toolbar
;
611 if( nStyle_
& SAL_FRAME_STYLE_PARTIAL_FULLSCREEN
)
612 eType
= WMAdaptor::windowType_Dock
;
614 GetDisplay()->getWMAdaptor()->
615 setFrameTypeAndDecoration( this,
618 hPresentationWindow
? NULL
: mpParent
);
620 if( (nStyle_
& (SAL_FRAME_STYLE_DEFAULT
|
621 SAL_FRAME_STYLE_OWNERDRAWDECORATION
|
622 SAL_FRAME_STYLE_FLOAT
|
623 SAL_FRAME_STYLE_INTRO
|
624 SAL_FRAME_STYLE_PARTIAL_FULLSCREEN
) )
625 == SAL_FRAME_STYLE_DEFAULT
)
626 pDisplay_
->getWMAdaptor()->maximizeFrame( this, true, true );
629 m_nWorkArea
= GetDisplay()->getWMAdaptor()->getCurrentWorkArea();
632 SetPointer( POINTER_ARROW
);
635 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
636 X11SalFrame::X11SalFrame( SalFrame
*pParent
, ULONG nSalFrameStyle
, SystemParentData
* pSystemParent
)
638 X11SalData
* pSalData
= GetX11SalData();
640 // initialize frame geometry
641 memset( &maGeometry
, 0, sizeof(maGeometry
) );
643 mpParent
= static_cast< X11SalFrame
* >( pParent
);
645 mbTransientForRoot
= false;
647 pDisplay_
= pSalData
->GetDisplay();
648 // insert frame in framelist
649 pDisplay_
->registerFrame( this );
652 mhShellWindow
= None
;
653 mhStackingWindow
= None
;
654 mhForeignParent
= None
;
655 mhBackgroundPixmap
= None
;
658 pFreeGraphics_
= NULL
;
668 mbSendExtKeyModChange
= false;
671 nShowState_
= SHOWSTATE_UNKNOWN
;
676 bAlwaysOnTop_
= FALSE
;
678 // set bViewable_ to TRUE: hack GetClientSize to report something
679 // different to 0/0 before first map
682 bDefaultPosition_
= TRUE
;
683 nVisibility_
= VisibilityFullyObscured
;
688 nScreenSaversTimeout_
= 0;
690 mpInputContext
= NULL
;
691 mbInputFocus
= False
;
693 maAlwaysOnTopRaiseTimer
.SetTimeoutHdl( LINK( this, X11SalFrame
, HandleAlwaysOnTopRaise
) );
694 maAlwaysOnTopRaiseTimer
.SetTimeout( 100 );
696 meWindowType
= WMAdaptor::windowType_Normal
;
697 mnDecorationFlags
= WMAdaptor::decoration_All
;
698 mbMaximizedVert
= false;
699 mbMaximizedHorz
= false;
701 mbFullScreen
= false;
703 mnIconID
= 1; // ICON_DEFAULT
705 m_pClipRectangles
= NULL
;
710 mpParent
->maChildren
.push_back( this );
712 Init( nSalFrameStyle
, GetDisplay()->GetDefaultScreenNumber(), pSystemParent
);
715 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
717 void X11SalFrame::passOnSaveYourSelf()
719 if( this == s_pSaveYourselfFrame
)
721 // pass on SaveYourself
722 const X11SalFrame
* pFrame
= NULL
;
723 const std::list
< SalFrame
* >& rFrames
= GetDisplay()->getFrames();
724 std::list
< SalFrame
* >::const_iterator it
= rFrames
.begin();
725 while( it
!= rFrames
.end() )
727 pFrame
= static_cast< const X11SalFrame
* >(*it
);
728 if( ! ( IsChildWindow() || pFrame
->mpParent
)
729 && pFrame
!= s_pSaveYourselfFrame
)
734 s_pSaveYourselfFrame
= (it
!= rFrames
.end() ) ? const_cast<X11SalFrame
*>(pFrame
) : NULL
;
735 if( s_pSaveYourselfFrame
)
739 a
[n
++] = pDisplay_
->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW
);
740 a
[n
++] = pDisplay_
->getWMAdaptor()->getAtom( WMAdaptor::WM_SAVE_YOURSELF
);
741 XSetWMProtocols( GetXDisplay(), s_pSaveYourselfFrame
->GetShellWindow(), a
, n
);
746 X11SalFrame::~X11SalFrame()
750 if( m_pClipRectangles
)
752 delete [] m_pClipRectangles
;
753 m_pClipRectangles
= NULL
;
754 m_nCurClipRect
= m_nMaxClipRect
= 0;
757 if( mhBackgroundPixmap
)
759 XSetWindowBackgroundPixmap( GetXDisplay(), GetWindow(), None
);
760 XFreePixmap( GetXDisplay(), mhBackgroundPixmap
);
763 if( mhStackingWindow
)
764 aPresentationReparentList
.remove( mhStackingWindow
);
766 // remove from parent's list
768 mpParent
->maChildren
.remove( this );
770 // deregister on SalDisplay
771 pDisplay_
->deregisterFrame( this );
773 // unselect all events, some may be still in the queue anyway
774 if( ! IsSysChildWindow() )
775 XSelectInput( GetXDisplay(), GetShellWindow(), 0 );
776 XSelectInput( GetXDisplay(), GetWindow(), 0 );
778 ShowFullScreen( FALSE
, 0 );
785 mpInputContext
->UnsetICFocus( this );
786 mpInputContext
->Unmap( this );
787 delete mpInputContext
;
790 if( GetWindow() == hPresentationWindow
)
792 hPresentationWindow
= None
;
793 doReparentPresentationDialogues( GetDisplay() );
798 pGraphics_
->DeInit();
804 pFreeGraphics_
->DeInit();
805 delete pFreeGraphics_
;
809 XDestroyWindow( GetXDisplay(), mhWindow
);
812 * check if there is only the status frame left
815 if( ! GetDisplay()->getFrames().empty() && I18NStatus::exists() )
817 SalFrame
* pStatusFrame
= I18NStatus::get().getStatusFrame();
818 std::list
< SalFrame
* >::const_iterator sit
= GetDisplay()->getFrames().begin();
820 && *sit
== pStatusFrame
821 && ++sit
== GetDisplay()->getFrames().end() )
822 vcl::I18NStatus::free();
825 passOnSaveYourSelf();
828 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
830 void X11SalFrame::SetExtendedFrameStyle( SalExtStyle nStyle
)
832 if( nStyle
!= mnExtStyle
&& ! IsChildWindow() )
836 XClassHint
* pClass
= XAllocClassHint();
837 rtl::OString aResHint
= X11SalData::getFrameResName( mnExtStyle
);
838 pClass
->res_name
= const_cast<char*>(aResHint
.getStr());
839 pClass
->res_class
= const_cast<char*>(X11SalData::getFrameClassName());
840 XSetClassHint( GetXDisplay(), GetShellWindow(), pClass
);
845 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
847 void X11SalFrame::SetBackgroundBitmap( SalBitmap
* pBitmap
)
849 if( mhBackgroundPixmap
)
851 XSetWindowBackgroundPixmap( GetXDisplay(), GetWindow(), None
);
852 XFreePixmap( GetXDisplay(), mhBackgroundPixmap
);
853 mhBackgroundPixmap
= None
;
857 X11SalBitmap
* pBM
= static_cast<X11SalBitmap
*>(pBitmap
);
858 Size aSize
= pBM
->GetSize();
859 if( aSize
.Width() && aSize
.Height() )
862 XCreatePixmap( GetXDisplay(),
866 GetDisplay()->GetVisual( m_nScreen
).GetDepth() );
867 if( mhBackgroundPixmap
)
870 aTwoRect
.mnSrcX
= aTwoRect
.mnSrcY
= aTwoRect
.mnDestX
= aTwoRect
.mnDestY
= 0;
871 aTwoRect
.mnSrcWidth
= aTwoRect
.mnDestWidth
= aSize
.Width();
872 aTwoRect
.mnSrcHeight
= aTwoRect
.mnDestHeight
= aSize
.Height();
873 pBM
->ImplDraw( mhBackgroundPixmap
,
875 GetDisplay()->GetVisual( m_nScreen
).GetDepth(),
876 aTwoRect
, GetDisplay()->GetCopyGC( m_nScreen
) );
877 XSetWindowBackgroundPixmap( GetXDisplay(), GetWindow(), mhBackgroundPixmap
);
883 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
885 const SystemChildData
* X11SalFrame::GetSystemData() const
887 X11SalFrame
*pFrame
= const_cast<X11SalFrame
*>(this);
888 pFrame
->maSystemChildData
.nSize
= sizeof( SystemChildData
);
889 pFrame
->maSystemChildData
.pDisplay
= GetXDisplay();
890 pFrame
->maSystemChildData
.aWindow
= pFrame
->GetWindow();
891 pFrame
->maSystemChildData
.pSalFrame
= pFrame
;
892 pFrame
->maSystemChildData
.pWidget
= NULL
;
893 pFrame
->maSystemChildData
.pVisual
= GetDisplay()->GetVisual( m_nScreen
).GetVisual();
894 pFrame
->maSystemChildData
.nScreen
= m_nScreen
;
895 pFrame
->maSystemChildData
.nDepth
= GetDisplay()->GetVisual( m_nScreen
).GetDepth();
896 pFrame
->maSystemChildData
.aColormap
= GetDisplay()->GetColormap( m_nScreen
).GetXColormap();
897 pFrame
->maSystemChildData
.pAppContext
= NULL
;
898 pFrame
->maSystemChildData
.aShellWindow
= pFrame
->GetShellWindow();
899 pFrame
->maSystemChildData
.pShellWidget
= NULL
;
900 return &maSystemChildData
;
903 SalGraphics
*X11SalFrame::GetGraphics()
910 pGraphics_
= pFreeGraphics_
;
911 pFreeGraphics_
= NULL
;
915 pGraphics_
= new X11SalGraphics();
916 pGraphics_
->Init( this, GetWindow(), m_nScreen
);
922 void X11SalFrame::ReleaseGraphics( SalGraphics
*pGraphics
)
924 DBG_ASSERT( pGraphics
== pGraphics_
, "SalFrame::ReleaseGraphics pGraphics!=pGraphics_" );
926 if( pGraphics
!= pGraphics_
)
929 pFreeGraphics_
= pGraphics_
;
933 void X11SalFrame::updateGraphics()
936 pGraphics_
->SetDrawable( GetWindow(), m_nScreen
);
938 pFreeGraphics_
->SetDrawable( GetWindow(), m_nScreen
);
941 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
943 void X11SalFrame::Enable( BOOL
/*bEnable*/ )
945 // NYI: enable/disable frame
948 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
950 void X11SalFrame::SetIcon( USHORT nIcon
)
952 if ( ! IsChildWindow() )
954 // 0 == default icon -> #1
960 XIconSize
*pIconSize
= NULL
;
963 if ( XGetIconSizes( GetXDisplay(), GetDisplay()->GetRootWindow( m_nScreen
), &pIconSize
, &nSizes
) )
965 #if OSL_DEBUG_LEVEL > 1
966 fprintf(stderr
, "X11SalFrame::SetIcon(): found %d IconSizes:\n", nSizes
);
969 const int ourLargestIconSize
= 48;
970 bool bFoundIconSize
= false;
973 for( i
=0; i
<nSizes
; i
++)
975 // select largest supported icon
977 // Note: olwm/olvwm reports a huge max icon size of
978 // 160x160 pixels; always choosing the max as the
979 // preferred icon size is apparently wrong under olvwm
980 // - so we keep the safe default |iconSize| when we see
981 // unreasonable large max icon sizes (> twice of our
982 // largest available icon) reported by XGetIconSizes.
983 if( pIconSize
[i
].max_width
> iconSize
984 && pIconSize
[i
].max_width
<= 2*ourLargestIconSize
)
986 iconSize
= pIconSize
[i
].max_width
;
987 bFoundIconSize
= true;
989 iconSize
= pIconSize
[i
].max_width
;
991 #if OSL_DEBUG_LEVEL > 1
992 fprintf(stderr
, "min: %d, %d\nmax: %d, %d\ninc: %d, %d\n\n",
993 pIconSize
[i
].min_width
, pIconSize
[i
].min_height
,
994 pIconSize
[i
].max_width
, pIconSize
[i
].max_height
,
995 pIconSize
[i
].width_inc
, pIconSize
[i
].height_inc
);
999 if ( !bFoundIconSize
)
1001 // Unless someone has fixed olwm/olvwm, we have rejected
1002 // the max icon size from |XGetIconSizes()|. Provide a
1003 // better icon size default value, in case our window manager
1005 const String
& rWM( pDisplay_
->getWMAdaptor()->getWindowManagerName() );
1007 if ( rWM
.EqualsAscii( "Olwm" ) )
1015 const String
& rWM( pDisplay_
->getWMAdaptor()->getWindowManagerName() );
1016 if( rWM
.EqualsAscii( "KWin" ) ) // assume KDE is running
1018 static bool bGnomeIconSize
= false;
1019 static bool bGnomeChecked
= false;
1020 if( ! bGnomeChecked
)
1024 Atom
* pProps
= XListProperties( GetXDisplay(),
1025 GetDisplay()->GetRootWindow( m_nScreen
),
1027 for( int i
= 0; i
< nCount
&& !bGnomeIconSize
; i
++ )
1029 char* pName
= XGetAtomName( GetXDisplay(), pProps
[i
] );
1030 if( !strcmp( pName
, "GNOME_PANEL_DESKTOP_AREA" ) )
1031 bGnomeIconSize
= true;
1038 if( bGnomeIconSize
)
1044 XWMHints
*pHints
= XGetWMHints( GetXDisplay(), GetShellWindow() );
1047 memcpy(&Hints
, pHints
, sizeof( XWMHints
));
1052 BOOL bOk
= SelectAppIconPixmap( GetDisplay(), m_nScreen
,
1054 pHints
->icon_pixmap
, pHints
->icon_mask
);
1057 // load default icon (0)
1058 bOk
= SelectAppIconPixmap( GetDisplay(), m_nScreen
,
1060 pHints
->icon_pixmap
, pHints
->icon_mask
);
1064 pHints
->flags
|= IconPixmapHint
;
1065 if( pHints
->icon_mask
)
1066 pHints
->flags
|= IconMaskHint
;
1068 XSetWMHints( GetXDisplay(), GetShellWindow(), pHints
);
1073 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1075 void X11SalFrame::SetMaxClientSize( long nWidth
, long nHeight
)
1077 if( ! IsChildWindow() )
1079 if( GetShellWindow() && (nStyle_
& (SAL_FRAME_STYLE_FLOAT
|SAL_FRAME_STYLE_OWNERDRAWDECORATION
) ) != SAL_FRAME_STYLE_FLOAT
)
1081 XSizeHints
* pHints
= XAllocSizeHints();
1083 XGetWMNormalHints( GetXDisplay(),
1088 pHints
->max_width
= nWidth
;
1089 pHints
->max_height
= nHeight
;
1090 pHints
->flags
|= PMaxSize
;
1091 XSetWMNormalHints( GetXDisplay(),
1099 void X11SalFrame::SetMinClientSize( long nWidth
, long nHeight
)
1101 if( ! IsChildWindow() )
1103 if( GetShellWindow() && (nStyle_
& (SAL_FRAME_STYLE_FLOAT
|SAL_FRAME_STYLE_OWNERDRAWDECORATION
) ) != SAL_FRAME_STYLE_FLOAT
)
1105 XSizeHints
* pHints
= XAllocSizeHints();
1107 XGetWMNormalHints( GetXDisplay(),
1112 pHints
->min_width
= nWidth
;
1113 pHints
->min_height
= nHeight
;
1114 pHints
->flags
|= PMinSize
;
1115 XSetWMNormalHints( GetXDisplay(),
1123 // Show + Pos (x,y,z) + Size (width,height)
1124 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1125 void X11SalFrame::Show( BOOL bVisible
, BOOL bNoActivate
)
1127 if( ( bVisible
&& bMapped_
)
1128 || ( !bVisible
&& !bMapped_
) )
1131 // HACK: this is a workaround for (at least) kwin
1132 // even though transient frames should be kept above their parent
1133 // this does not necessarily hold true for DOCK type windows
1134 // so artificially set ABOVE and remove it again on hide
1135 if( mpParent
&& (mpParent
->nStyle_
& SAL_FRAME_STYLE_PARTIAL_FULLSCREEN
) )
1136 pDisplay_
->getWMAdaptor()->enableAlwaysOnTop( this, bVisible
);
1138 bMapped_
= bVisible
;
1139 bViewable_
= bVisible
;
1143 SessionManagerClient::open(); // will simply return after the first time
1146 if( ! (nStyle_
& SAL_FRAME_STYLE_INTRO
) )
1148 // hide all INTRO frames
1149 const std::list
< SalFrame
* >& rFrames
= GetDisplay()->getFrames();
1150 for( std::list
< SalFrame
* >::const_iterator it
= rFrames
.begin(); it
!= rFrames
.end(); ++it
)
1152 const X11SalFrame
* pFrame
= static_cast< const X11SalFrame
* >(*it
);
1153 // look for intro bit map; if present, hide it
1154 if( pFrame
->nStyle_
& SAL_FRAME_STYLE_INTRO
)
1156 if( pFrame
->bMapped_
)
1157 const_cast<X11SalFrame
*>(pFrame
)->Show( FALSE
);
1162 // update NET_WM_STATE which may have been deleted due to earlier Show(FALSE)
1163 if( nShowState_
== SHOWSTATE_HIDDEN
)
1164 GetDisplay()->getWMAdaptor()->frameIsMapping( this );
1168 * Actually this is rather exotic and currently happens only in conjunction
1169 * with the basic dialogue editor,
1170 * which shows a frame and instantly hides it again. After that the
1171 * editor window is shown and the WM takes this as an opportunity
1172 * to show our hidden transient frame also. So Show( FALSE ) must
1173 * withdraw the frame AND delete the WM_TRANSIENT_FOR property.
1174 * In case the frame is shown again, the transient hint must be restored here.
1176 if( ! IsChildWindow()
1177 && ! IsOverrideRedirect()
1178 && ! IsFloatGrabWindow()
1182 GetDisplay()->getWMAdaptor()->changeReferenceFrame( this, mpParent
);
1185 // #i45160# switch to desktop where a dialog with parent will appear
1186 if( mpParent
&& mpParent
->m_nWorkArea
!= m_nWorkArea
)
1187 GetDisplay()->getWMAdaptor()->switchToWorkArea( mpParent
->m_nWorkArea
);
1189 if( IsFloatGrabWindow() &&
1191 nVisibleFloats
== 0 &&
1192 ! GetDisplay()->GetCaptureFrame() )
1195 * outsmart KWin's "focus strictly under mouse" mode
1196 * which insists on taking the focus from the document
1197 * to the new float. Grab focus to parent frame BEFORE
1198 * showing the float (cannot grab it to the float
1201 XGrabPointer( GetXDisplay(),
1202 mpParent
->GetWindow(),
1204 PointerMotionMask
| ButtonPressMask
| ButtonReleaseMask
,
1208 mpParent
? mpParent
->GetCursor() : None
,
1213 XLIB_Time nUserTime
= 0;
1214 if( ! bNoActivate
&& (nStyle_
& (SAL_FRAME_STYLE_OWNERDRAWDECORATION
|SAL_FRAME_STYLE_TOOLWINDOW
)) == 0 )
1216 if( GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("Metacity") )
1217 nUserTime
= pDisplay_
->GetLastUserEventTime( true );
1219 nUserTime
= pDisplay_
->GetLastUserEventTime();
1221 GetDisplay()->getWMAdaptor()->setUserTime( this, nUserTime
);
1223 // actually map the window
1225 askForXEmbedFocus( 0 );
1228 if( GetWindow() != GetShellWindow() && ! IsSysChildWindow() )
1230 if( IsChildWindow() )
1231 XMapWindow( GetXDisplay(), GetShellWindow() );
1232 XSelectInput( GetXDisplay(), GetShellWindow(), CLIENT_EVENTS
);
1234 if( nStyle_
& SAL_FRAME_STYLE_FLOAT
)
1235 XMapRaised( GetXDisplay(), GetWindow() );
1237 XMapWindow( GetXDisplay(), GetWindow() );
1239 XSelectInput( GetXDisplay(), GetWindow(), CLIENT_EVENTS
);
1241 if( maGeometry
.nWidth
> 0
1242 && maGeometry
.nHeight
> 0
1243 && ( nWidth_
!= (int)maGeometry
.nWidth
1244 || nHeight_
!= (int)maGeometry
.nHeight
) )
1246 nWidth_
= maGeometry
.nWidth
;
1247 nHeight_
= maGeometry
.nHeight
;
1250 XSync( GetXDisplay(), False
);
1252 if( IsFloatGrabWindow() )
1256 * Sawfish and twm can be switched to enter-exit focus behaviour. In this case
1257 * we must grab the pointer else the dumb WM will put the focus to the
1258 * override-redirect float window. The application window will be deactivated
1259 * which causes that the floats are destroyed, so the user can never click on
1260 * a menu because it vanishes as soon as he enters it.
1263 if( nVisibleFloats
== 1 && ! GetDisplay()->GetCaptureFrame() )
1265 /* #i39420# now move grab to the new float window */
1266 XGrabPointer( GetXDisplay(),
1269 PointerMotionMask
| ButtonPressMask
| ButtonReleaseMask
,
1273 mpParent
? mpParent
->GetCursor() : None
,
1278 CallCallback( SALEVENT_RESIZE
, NULL
);
1281 * sometimes a message box/dialogue is brought up when a frame is not mapped
1282 * the corresponding TRANSIENT_FOR hint is then set to the root window
1283 * so that the dialogue shows in all cases. Correct it here if the
1284 * frame is shown afterwards.
1286 if( ! IsChildWindow()
1287 && ! IsOverrideRedirect()
1288 && ! IsFloatGrabWindow()
1291 for( std::list
< X11SalFrame
* >::const_iterator it
= maChildren
.begin();
1292 it
!= maChildren
.end(); ++it
)
1294 if( (*it
)->mbTransientForRoot
)
1295 GetDisplay()->getWMAdaptor()->changeReferenceFrame( *it
, this );
1299 * leave SHOWSTATE_UNKNOWN as this indicates first mapping
1300 * and is only reset int HandleSizeEvent
1302 if( nShowState_
!= SHOWSTATE_UNKNOWN
)
1303 nShowState_
= SHOWSTATE_NORMAL
;
1306 * #98107# plugged windows don't necessarily get the
1307 * focus on show because the parent may already be mapped
1308 * and have the focus. So try to set the focus
1309 * to the child on Show(TRUE)
1311 if( (nStyle_
& SAL_FRAME_STYLE_PLUG
) && ! m_bXEmbed
)
1312 XSetInputFocus( GetXDisplay(),
1319 // push this frame so it will be in front of its siblings
1320 // only necessary for insane transient behaviour of Dtwm/olwm
1321 mpParent
->maChildren
.remove( this );
1322 mpParent
->maChildren
.push_front(this);
1327 #if OSL_DEBUG_LEVEL > 1
1328 if( nStyle_
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
)
1329 fprintf( stderr
, "hide on ownerdraw\n" );
1332 if( getInputContext() )
1333 getInputContext()->Unmap( this );
1335 if( ! IsChildWindow() )
1337 /* FIXME: Is deleting the property really necessary ? It hurts
1338 * owner drawn windows at least.
1340 if( mpParent
&& ! (nStyle_
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) )
1341 XDeleteProperty( GetXDisplay(), GetShellWindow(), GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::WM_TRANSIENT_FOR
) );
1342 XWithdrawWindow( GetXDisplay(), GetShellWindow(), m_nScreen
);
1344 else if( ! m_bXEmbed
)
1345 XUnmapWindow( GetXDisplay(), GetWindow() );
1347 nShowState_
= SHOWSTATE_HIDDEN
;
1348 if( IsFloatGrabWindow() && nVisibleFloats
)
1351 if( nVisibleFloats
== 0 && ! GetDisplay()->GetCaptureFrame() )
1352 XUngrabPointer( GetXDisplay(),
1355 // flush here; there may be a very seldom race between
1356 // the display connection used for clipboard and our connection
1361 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1362 void X11SalFrame::ToTop( USHORT nFlags
)
1364 if( ( nFlags
& SAL_FRAME_TOTOP_RESTOREWHENMIN
)
1365 && ! ( nStyle_
& SAL_FRAME_STYLE_FLOAT
)
1366 && nShowState_
!= SHOWSTATE_HIDDEN
1367 && nShowState_
!= SHOWSTATE_UNKNOWN
1370 GetDisplay()->getWMAdaptor()->frameIsMapping( this );
1371 if( GetWindow() != GetShellWindow() && ! IsSysChildWindow() )
1372 XMapWindow( GetXDisplay(), GetShellWindow() );
1373 XMapWindow( GetXDisplay(), GetWindow() );
1376 XLIB_Window aToTopWindow
= IsSysChildWindow() ? GetWindow() : GetShellWindow();
1377 if( ! (nFlags
& SAL_FRAME_TOTOP_GRABFOCUS_ONLY
) )
1379 XRaiseWindow( GetXDisplay(), aToTopWindow
);
1380 if( ! GetDisplay()->getWMAdaptor()->isTransientBehaviourAsExpected() )
1381 for( std::list
< X11SalFrame
* >::const_iterator it
= maChildren
.begin();
1382 it
!= maChildren
.end(); ++it
)
1383 (*it
)->ToTop( nFlags
& ~SAL_FRAME_TOTOP_GRABFOCUS
);
1386 if( ( ( nFlags
& SAL_FRAME_TOTOP_GRABFOCUS
) || ( nFlags
& SAL_FRAME_TOTOP_GRABFOCUS_ONLY
) )
1390 askForXEmbedFocus( 0 );
1392 XSetInputFocus( GetXDisplay(), aToTopWindow
, RevertToParent
, CurrentTime
);
1395 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1396 void X11SalFrame::GetWorkArea( Rectangle
& rWorkArea
)
1398 rWorkArea
= pDisplay_
->getWMAdaptor()->getWorkArea( 0 );
1400 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1401 void X11SalFrame::GetClientSize( long &rWidth
, long &rHeight
)
1405 rWidth
= rHeight
= 0;
1409 rWidth
= maGeometry
.nWidth
;
1410 rHeight
= maGeometry
.nHeight
;
1412 if( !rWidth
|| !rHeight
)
1414 XWindowAttributes aAttrib
;
1416 XGetWindowAttributes( GetXDisplay(), GetWindow(), &aAttrib
);
1418 maGeometry
.nWidth
= rWidth
= aAttrib
.width
;
1419 maGeometry
.nHeight
= rHeight
= aAttrib
.height
;
1423 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1425 void X11SalFrame::SetWindowGravity (int nGravity
) const
1427 if( ! IsChildWindow() )
1429 XSizeHints
* pHint
= XAllocSizeHints();
1432 XGetWMNormalHints (GetXDisplay(), GetShellWindow(), pHint
, &nFlag
);
1433 pHint
->flags
|= PWinGravity
;
1434 pHint
->win_gravity
= nGravity
;
1436 XSetWMNormalHints (GetXDisplay(), GetShellWindow(), pHint
);
1437 XSync (GetXDisplay(), False
);
1443 void X11SalFrame::Center( )
1445 int nX
, nY
, nScreenWidth
, nScreenHeight
;
1446 int nRealScreenWidth
, nRealScreenHeight
;
1447 int nScreenX
= 0, nScreenY
= 0;
1449 const Size
& aScreenSize
= GetDisplay()->getDataForScreen( m_nScreen
).m_aSize
;
1450 nScreenWidth
= aScreenSize
.Width();
1451 nScreenHeight
= aScreenSize
.Height();
1452 nRealScreenWidth
= nScreenWidth
;
1453 nRealScreenHeight
= nScreenHeight
;
1455 if( GetDisplay()->IsXinerama() )
1457 // get xinerama screen we are on
1458 // if there is a parent, use its center for screen determination
1459 // else use the pointer
1460 XLIB_Window aRoot
, aChild
;
1461 int root_x
, root_y
, x
, y
;
1465 root_x
= mpParent
->maGeometry
.nX
+ mpParent
->maGeometry
.nWidth
/2;
1466 root_y
= mpParent
->maGeometry
.nY
+ mpParent
->maGeometry
.nHeight
/2;
1469 XQueryPointer( GetXDisplay(),
1475 const std::vector
< Rectangle
>& rScreens
= GetDisplay()->GetXineramaScreens();
1476 for( unsigned int i
= 0; i
< rScreens
.size(); i
++ )
1477 if( rScreens
[i
].IsInside( Point( root_x
, root_y
) ) )
1479 nScreenX
= rScreens
[i
].Left();
1480 nScreenY
= rScreens
[i
].Top();
1481 nRealScreenWidth
= rScreens
[i
].GetWidth();
1482 nRealScreenHeight
= rScreens
[i
].GetHeight();
1489 X11SalFrame
* pFrame
= mpParent
;
1490 while( pFrame
->mpParent
)
1491 pFrame
= pFrame
->mpParent
;
1492 if( pFrame
->maGeometry
.nWidth
< 1 || pFrame
->maGeometry
.nHeight
< 1 )
1495 pFrame
->GetPosSize( aRect
);
1496 pFrame
->maGeometry
.nX
= aRect
.Left();
1497 pFrame
->maGeometry
.nY
= aRect
.Top();
1498 pFrame
->maGeometry
.nWidth
= aRect
.GetWidth();
1499 pFrame
->maGeometry
.nHeight
= aRect
.GetHeight();
1502 if( pFrame
->nStyle_
& SAL_FRAME_STYLE_PLUG
)
1505 unsigned int bw
, depth
;
1506 XGetGeometry( GetXDisplay(),
1507 pFrame
->GetShellWindow(),
1509 &nScreenX
, &nScreenY
,
1510 (unsigned int*)&nScreenWidth
,
1511 (unsigned int*)&nScreenHeight
,
1516 nScreenX
= pFrame
->maGeometry
.nX
;
1517 nScreenY
= pFrame
->maGeometry
.nY
;
1518 nScreenWidth
= pFrame
->maGeometry
.nWidth
;
1519 nScreenHeight
= pFrame
->maGeometry
.nHeight
;
1523 if( mpParent
&& mpParent
->nShowState_
== SHOWSTATE_NORMAL
)
1525 if( maGeometry
.nWidth
>= mpParent
->maGeometry
.nWidth
&&
1526 maGeometry
.nHeight
>= mpParent
->maGeometry
.nHeight
)
1533 // center the window relative to the top level frame
1534 nX
= (nScreenWidth
- (int)maGeometry
.nWidth
) / 2 + nScreenX
;
1535 nY
= (nScreenHeight
- (int)maGeometry
.nHeight
) / 2 + nScreenY
;
1540 // center the window relative to screen
1541 nX
= (nRealScreenWidth
- (int)maGeometry
.nWidth
) / 2 + nScreenX
;
1542 nY
= (nRealScreenHeight
- (int)maGeometry
.nHeight
) / 2 + nScreenY
;
1544 nX
= nX
< 0 ? 0 : nX
;
1545 nY
= nY
< 0 ? 0 : nY
;
1547 bDefaultPosition_
= False
;
1550 nX
-= mpParent
->maGeometry
.nX
;
1551 nY
-= mpParent
->maGeometry
.nY
;
1554 Point
aPoint(nX
, nY
);
1555 SetPosSize( Rectangle( aPoint
, Size( maGeometry
.nWidth
, maGeometry
.nHeight
) ) );
1558 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1559 void X11SalFrame::updateScreenNumber()
1561 if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 )
1563 Point
aPoint( maGeometry
.nX
, maGeometry
.nY
);
1564 const std::vector
<Rectangle
>& rScreenRects( GetDisplay()->GetXineramaScreens() );
1565 size_t nScreens
= rScreenRects
.size();
1566 for( size_t i
= 0; i
< nScreens
; i
++ )
1568 if( rScreenRects
[i
].IsInside( aPoint
) )
1570 maGeometry
.nScreenNumber
= static_cast<unsigned int>(i
);
1576 maGeometry
.nScreenNumber
= static_cast<unsigned int>(m_nScreen
);
1579 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1580 void X11SalFrame::SetPosSize( long nX
, long nY
, long nWidth
, long nHeight
, USHORT nFlags
)
1582 if( nStyle_
& SAL_FRAME_STYLE_PLUG
)
1585 // relative positioning in X11SalFrame::SetPosSize
1586 Rectangle
aPosSize( Point( maGeometry
.nX
, maGeometry
.nY
), Size( maGeometry
.nWidth
, maGeometry
.nHeight
) );
1589 if( ! ( nFlags
& SAL_FRAME_POSSIZE_X
) )
1591 nX
= aPosSize
.Left();
1593 nX
-= mpParent
->maGeometry
.nX
;
1595 if( ! ( nFlags
& SAL_FRAME_POSSIZE_Y
) )
1597 nY
= aPosSize
.Top();
1599 nY
-= mpParent
->maGeometry
.nY
;
1601 if( ! ( nFlags
& SAL_FRAME_POSSIZE_WIDTH
) )
1602 nWidth
= aPosSize
.GetWidth();
1603 if( ! ( nFlags
& SAL_FRAME_POSSIZE_HEIGHT
) )
1604 nHeight
= aPosSize
.GetHeight();
1606 aPosSize
= Rectangle( Point( nX
, nY
), Size( nWidth
, nHeight
) );
1608 if( ! ( nFlags
& ( SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
) ) )
1610 if( bDefaultPosition_
)
1612 maGeometry
.nWidth
= aPosSize
.GetWidth();
1613 maGeometry
.nHeight
= aPosSize
.GetHeight();
1617 SetSize( Size( nWidth
, nHeight
) );
1620 SetPosSize( aPosSize
);
1621 bDefaultPosition_
= False
;
1624 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1625 void X11SalFrame::SetAlwaysOnTop( BOOL bOnTop
)
1627 if( ! IsOverrideRedirect() )
1629 bAlwaysOnTop_
= bOnTop
;
1630 pDisplay_
->getWMAdaptor()->enableAlwaysOnTop( this, bOnTop
);
1634 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1636 #define _FRAMESTATE_MASK_GEOMETRY \
1637 (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y | \
1638 SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT)
1639 #define _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY \
1640 (SAL_FRAMESTATE_MASK_MAXIMIZED_X | SAL_FRAMESTATE_MASK_MAXIMIZED_Y | \
1641 SAL_FRAMESTATE_MASK_MAXIMIZED_WIDTH | SAL_FRAMESTATE_MASK_MAXIMIZED_HEIGHT)
1643 void X11SalFrame::SetWindowState( const SalFrameState
*pState
)
1648 // Request for position or size change
1649 if (pState
->mnMask
& _FRAMESTATE_MASK_GEOMETRY
)
1652 bool bDoAdjust
= false;
1655 * if maximized, set restore size and guess maximized size from last time
1656 * in state change below maximize window
1658 if( ! IsChildWindow() &&
1659 (pState
->mnMask
& SAL_FRAMESTATE_MASK_STATE
) &&
1660 (pState
->mnState
& SAL_FRAMESTATE_MAXIMIZED
) &&
1661 (pState
->mnMask
& _FRAMESTATE_MASK_GEOMETRY
) == _FRAMESTATE_MASK_GEOMETRY
&&
1662 (pState
->mnMask
& _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY
) == _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY
1665 XSizeHints
* pHints
= XAllocSizeHints();
1667 XGetWMNormalHints( GetXDisplay(),
1671 pHints
->flags
|= PPosition
| PWinGravity
;
1672 pHints
->x
= pState
->mnX
;
1673 pHints
->y
= pState
->mnY
;
1674 pHints
->win_gravity
= pDisplay_
->getWMAdaptor()->getPositionWinGravity();
1675 XSetWMNormalHints( GetXDisplay(),
1680 XMoveResizeWindow( GetXDisplay(), GetShellWindow(),
1681 pState
->mnX
, pState
->mnY
,
1682 pState
->mnWidth
, pState
->mnHeight
);
1683 // guess maximized geometry from last time
1684 maGeometry
.nX
= pState
->mnMaximizedX
;
1685 maGeometry
.nY
= pState
->mnMaximizedY
;
1686 maGeometry
.nWidth
= pState
->mnMaximizedWidth
;
1687 maGeometry
.nHeight
= pState
->mnMaximizedHeight
;
1688 updateScreenNumber();
1692 // initialize with current geometry
1693 if ((pState
->mnMask
& _FRAMESTATE_MASK_GEOMETRY
) != _FRAMESTATE_MASK_GEOMETRY
)
1694 GetPosSize (aPosSize
);
1696 // change requested properties
1697 if (pState
->mnMask
& SAL_FRAMESTATE_MASK_X
)
1699 aPosSize
.setX (pState
->mnX
);
1701 if (pState
->mnMask
& SAL_FRAMESTATE_MASK_Y
)
1703 aPosSize
.setY (pState
->mnY
);
1705 if (pState
->mnMask
& SAL_FRAMESTATE_MASK_WIDTH
)
1707 long nWidth
= pState
->mnWidth
> 0 ? pState
->mnWidth
- 1 : 0;
1708 aPosSize
.setWidth (nWidth
);
1711 if (pState
->mnMask
& SAL_FRAMESTATE_MASK_HEIGHT
)
1713 int nHeight
= pState
->mnHeight
> 0 ? pState
->mnHeight
- 1 : 0;
1714 aPosSize
.setHeight (nHeight
);
1718 const Size
& aScreenSize
= pDisplay_
->getDataForScreen( m_nScreen
).m_aSize
;
1719 const WMAdaptor
*pWM
= GetDisplay()->getWMAdaptor();
1721 if( bDoAdjust
&& aPosSize
.GetWidth() <= aScreenSize
.Width()
1722 && aPosSize
.GetHeight() <= aScreenSize
.Height() )
1724 SalFrameGeometry aGeom
= maGeometry
;
1726 if( ! (nStyle_
& ( SAL_FRAME_STYLE_FLOAT
| SAL_FRAME_STYLE_PLUG
) ) &&
1728 aGeom
.nLeftDecoration
== 0 &&
1729 aGeom
.nTopDecoration
== 0 )
1731 aGeom
= mpParent
->maGeometry
;
1732 if( aGeom
.nLeftDecoration
== 0 &&
1733 aGeom
.nTopDecoration
== 0 )
1735 aGeom
.nLeftDecoration
= 5;
1736 aGeom
.nTopDecoration
= 20;
1737 aGeom
.nRightDecoration
= 5;
1738 aGeom
.nBottomDecoration
= 5;
1742 // adjust position so that frame fits onto screen
1743 if( aPosSize
.Right()+(long)aGeom
.nRightDecoration
> aScreenSize
.Width()-1 )
1744 aPosSize
.Move( (long)aScreenSize
.Width() - (long)aPosSize
.Right() - (long)aGeom
.nRightDecoration
, 0 );
1745 if( aPosSize
.Bottom()+(long)aGeom
.nBottomDecoration
> aScreenSize
.Height()-1 )
1746 aPosSize
.Move( 0, (long)aScreenSize
.Height() - (long)aPosSize
.Bottom() - (long)aGeom
.nBottomDecoration
);
1747 if( aPosSize
.Left() < (long)aGeom
.nLeftDecoration
)
1748 aPosSize
.Move( (long)aGeom
.nLeftDecoration
- (long)aPosSize
.Left(), 0 );
1749 if( aPosSize
.Top() < (long)aGeom
.nTopDecoration
)
1750 aPosSize
.Move( 0, (long)aGeom
.nTopDecoration
- (long)aPosSize
.Top() );
1753 // resize with new args
1754 if (pWM
->supportsICCCMPos())
1757 aPosSize
.Move( -mpParent
->maGeometry
.nX
,
1758 -mpParent
->maGeometry
.nY
);
1759 SetPosSize( aPosSize
);
1760 bDefaultPosition_
= False
;
1763 SetPosSize( 0, 0, aPosSize
.GetWidth(), aPosSize
.GetHeight(), SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
);
1767 // request for status change
1768 if (pState
->mnMask
& SAL_FRAMESTATE_MASK_STATE
)
1770 if (pState
->mnState
& SAL_FRAMESTATE_MAXIMIZED
)
1772 nShowState_
= SHOWSTATE_NORMAL
;
1773 if( ! (pState
->mnState
& (SAL_FRAMESTATE_MAXIMIZED_HORZ
|SAL_FRAMESTATE_MAXIMIZED_VERT
) ) )
1777 bool bHorz
= (pState
->mnState
& SAL_FRAMESTATE_MAXIMIZED_HORZ
) ? true : false;
1778 bool bVert
= (pState
->mnState
& SAL_FRAMESTATE_MAXIMIZED_VERT
) ? true : false;
1779 GetDisplay()->getWMAdaptor()->maximizeFrame( this, bHorz
, bVert
);
1781 maRestorePosSize
.Left() = pState
->mnX
;
1782 maRestorePosSize
.Top() = pState
->mnY
;
1783 maRestorePosSize
.Right() = maRestorePosSize
.Left() + pState
->mnWidth
;
1784 maRestorePosSize
.Right() = maRestorePosSize
.Left() + pState
->mnHeight
;
1786 else if( mbMaximizedHorz
|| mbMaximizedVert
)
1787 GetDisplay()->getWMAdaptor()->maximizeFrame( this, false, false );
1789 if (pState
->mnState
& SAL_FRAMESTATE_MINIMIZED
)
1791 if (nShowState_
== SHOWSTATE_UNKNOWN
)
1792 nShowState_
= SHOWSTATE_NORMAL
;
1795 if (pState
->mnState
& SAL_FRAMESTATE_NORMAL
)
1797 if (nShowState_
!= SHOWSTATE_NORMAL
)
1800 if (pState
->mnState
& SAL_FRAMESTATE_ROLLUP
)
1801 GetDisplay()->getWMAdaptor()->shade( this, true );
1805 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1806 BOOL
X11SalFrame::GetWindowState( SalFrameState
* pState
)
1808 if( SHOWSTATE_MINIMIZED
== nShowState_
)
1809 pState
->mnState
= SAL_FRAMESTATE_MINIMIZED
;
1811 pState
->mnState
= SAL_FRAMESTATE_NORMAL
;
1814 if( maRestorePosSize
.IsEmpty() )
1815 GetPosSize( aPosSize
);
1817 aPosSize
= maRestorePosSize
;
1819 if( mbMaximizedHorz
)
1820 pState
->mnState
|= SAL_FRAMESTATE_MAXIMIZED_HORZ
;
1821 if( mbMaximizedVert
)
1822 pState
->mnState
|= SAL_FRAMESTATE_MAXIMIZED_VERT
;
1824 pState
->mnState
|= SAL_FRAMESTATE_ROLLUP
;
1826 pState
->mnX
= aPosSize
.Left();
1827 pState
->mnY
= aPosSize
.Top();
1828 pState
->mnWidth
= aPosSize
.GetWidth();
1829 pState
->mnHeight
= aPosSize
.GetHeight();
1831 pState
->mnMask
= _FRAMESTATE_MASK_GEOMETRY
| SAL_FRAMESTATE_MASK_STATE
;
1834 if (! maRestorePosSize
.IsEmpty() )
1836 GetPosSize( aPosSize
);
1837 pState
->mnState
|= SAL_FRAMESTATE_MAXIMIZED
;
1838 pState
->mnMaximizedX
= aPosSize
.Left();
1839 pState
->mnMaximizedY
= aPosSize
.Top();
1840 pState
->mnMaximizedWidth
= aPosSize
.GetWidth();
1841 pState
->mnMaximizedHeight
= aPosSize
.GetHeight();
1842 pState
->mnMask
|= _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY
;
1848 // ----------------------------------------------------------------------------
1849 // get a screenshot of the current frame including window manager decoration
1850 SalBitmap
* X11SalFrame::SnapShot()
1852 Display
* pDisplay
= GetXDisplay();
1854 // make sure the frame has been reparented and all paint timer have been
1858 XSync(pDisplay
, False
);
1859 Application::Reschedule ();
1861 while (XPending(pDisplay
));
1864 aVal
.Nanosec
= 50000000;
1865 osl_waitThread( &aVal
);
1868 XSync(pDisplay
, False
);
1869 Application::Reschedule ();
1871 while (XPending(pDisplay
));
1873 // get the most outer window, usually the window manager decoration
1874 Drawable hWindow
= None
;
1875 if (IsOverrideRedirect())
1876 hWindow
= GetDrawable();
1878 if (hPresentationWindow
!= None
)
1879 hWindow
= hPresentationWindow
;
1881 hWindow
= GetStackingWindow();
1883 // query the contents of the window
1884 if (hWindow
!= None
)
1886 X11SalBitmap
*pBmp
= new X11SalBitmap
;
1887 if (pBmp
->SnapShot (pDisplay
, hWindow
))
1896 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1898 // native menu implementation - currently empty
1899 void X11SalFrame::DrawMenuBar()
1903 void X11SalFrame::SetMenu( SalMenu
* )
1907 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1908 void X11SalFrame::GetPosSize( Rectangle
&rPosSize
)
1910 if( maGeometry
.nWidth
< 1 || maGeometry
.nHeight
< 1 )
1912 const Size
& aScreenSize
= pDisplay_
->getDataForScreen( m_nScreen
).m_aSize
;
1913 long w
= aScreenSize
.Width() - maGeometry
.nLeftDecoration
- maGeometry
.nRightDecoration
;
1914 long h
= aScreenSize
.Height() - maGeometry
.nTopDecoration
- maGeometry
.nBottomDecoration
;
1916 rPosSize
= Rectangle( Point( maGeometry
.nX
, maGeometry
.nY
), Size( w
, h
) );
1919 rPosSize
= Rectangle( Point( maGeometry
.nX
, maGeometry
.nY
),
1920 Size( maGeometry
.nWidth
, maGeometry
.nHeight
) );
1923 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1924 void X11SalFrame::SetSize( const Size
&rSize
)
1926 if( rSize
.Width() > 0 && rSize
.Height() > 0 )
1928 if( ! ( nStyle_
& SAL_FRAME_STYLE_SIZEABLE
)
1929 && ! IsChildWindow()
1930 && ( nStyle_
& (SAL_FRAME_STYLE_FLOAT
|SAL_FRAME_STYLE_OWNERDRAWDECORATION
) ) != SAL_FRAME_STYLE_FLOAT
)
1932 XSizeHints
* pHints
= XAllocSizeHints();
1934 XGetWMNormalHints( GetXDisplay(),
1939 pHints
->min_width
= rSize
.Width();
1940 pHints
->min_height
= rSize
.Height();
1941 pHints
->max_width
= rSize
.Width();
1942 pHints
->max_height
= rSize
.Height();
1943 pHints
->flags
|= PMinSize
| PMaxSize
;
1944 XSetWMNormalHints( GetXDisplay(),
1949 XResizeWindow( GetXDisplay(), IsSysChildWindow() ? GetWindow() : GetShellWindow(), rSize
.Width(), rSize
.Height() );
1950 if( GetWindow() != GetShellWindow() )
1952 if( (nStyle_
& SAL_FRAME_STYLE_PLUG
) )
1953 XMoveResizeWindow( GetXDisplay(), GetWindow(), 0, 0, rSize
.Width(), rSize
.Height() );
1955 XResizeWindow( GetXDisplay(), GetWindow(), rSize
.Width(), rSize
.Height() );
1958 maGeometry
.nWidth
= rSize
.Width();
1959 maGeometry
.nHeight
= rSize
.Height();
1961 // allow the external status window to reposition
1962 if (mbInputFocus
&& mpInputContext
!= NULL
)
1963 mpInputContext
->SetICFocus ( this );
1967 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1969 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1971 void X11SalFrame::SetPosSize( const Rectangle
&rPosSize
)
1973 XWindowChanges values
;
1974 values
.x
= rPosSize
.Left();
1975 values
.y
= rPosSize
.Top();
1976 values
.width
= rPosSize
.GetWidth();
1977 values
.height
= rPosSize
.GetHeight();
1979 if( !values
.width
|| !values
.height
)
1982 if( mpParent
&& ! IsSysChildWindow() )
1984 // --- RTL --- (mirror window pos)
1985 if( Application::GetSettings().GetLayoutRTL() )
1986 values
.x
= mpParent
->maGeometry
.nWidth
-values
.width
-1-values
.x
;
1989 // coordinates are relative to parent, so translate to root coordinates
1990 XTranslateCoordinates( GetDisplay()->GetDisplay(),
1991 mpParent
->GetWindow(),
1992 GetDisplay()->GetRootWindow( m_nScreen
),
1994 &values
.x
, &values
.y
,
1998 bool bMoved
= false;
1999 bool bSized
= false;
2000 if( values
.x
!= maGeometry
.nX
|| values
.y
!= maGeometry
.nY
)
2002 if( values
.width
!= (int)maGeometry
.nWidth
|| values
.height
!= (int)maGeometry
.nHeight
)
2005 if( ! ( nStyle_
& ( SAL_FRAME_STYLE_PLUG
| SAL_FRAME_STYLE_FLOAT
) )
2006 && !(pDisplay_
->GetProperties() & PROPERTY_SUPPORT_WM_ClientPos
) )
2008 values
.x
-= maGeometry
.nLeftDecoration
;
2009 values
.y
-= maGeometry
.nTopDecoration
;
2012 // do net set WMNormalHints for ..
2016 // popups (menu, help window, etc.)
2017 && (nStyle_
& (SAL_FRAME_STYLE_FLOAT
|SAL_FRAME_STYLE_OWNERDRAWDECORATION
) ) != SAL_FRAME_STYLE_FLOAT
2018 // shown, sizeable windows
2019 && ( nShowState_
== SHOWSTATE_UNKNOWN
||
2020 nShowState_
== SHOWSTATE_HIDDEN
||
2021 ! ( nStyle_
& SAL_FRAME_STYLE_SIZEABLE
)
2025 XSizeHints
* pHints
= XAllocSizeHints();
2027 XGetWMNormalHints( GetXDisplay(),
2032 if( ! ( nStyle_
& SAL_FRAME_STYLE_SIZEABLE
) )
2034 pHints
->min_width
= rPosSize
.GetWidth();
2035 pHints
->min_height
= rPosSize
.GetHeight();
2036 pHints
->max_width
= rPosSize
.GetWidth();
2037 pHints
->max_height
= rPosSize
.GetHeight();
2038 pHints
->flags
|= PMinSize
| PMaxSize
;
2040 if( nShowState_
== SHOWSTATE_UNKNOWN
|| nShowState_
== SHOWSTATE_HIDDEN
)
2042 pHints
->flags
|= PPosition
| PWinGravity
;
2043 pHints
->x
= values
.x
;
2044 pHints
->y
= values
.y
;
2045 pHints
->win_gravity
= pDisplay_
->getWMAdaptor()->getPositionWinGravity();
2047 XSetWMNormalHints( GetXDisplay(),
2053 XMoveResizeWindow( GetXDisplay(), IsSysChildWindow() ? GetWindow() : GetShellWindow(), values
.x
, values
.y
, values
.width
, values
.height
);
2054 if( GetShellWindow() != GetWindow() )
2056 if( (nStyle_
& SAL_FRAME_STYLE_PLUG
) )
2057 XMoveResizeWindow( GetXDisplay(), GetWindow(), 0, 0, values
.width
, values
.height
);
2059 XMoveResizeWindow( GetXDisplay(), GetWindow(), values
.x
, values
.y
, values
.width
, values
.height
);
2062 maGeometry
.nX
= values
.x
;
2063 maGeometry
.nY
= values
.y
;
2064 maGeometry
.nWidth
= values
.width
;
2065 maGeometry
.nHeight
= values
.height
;
2066 if( IsSysChildWindow() && mpParent
)
2068 // translate back to root coordinates
2069 maGeometry
.nX
+= mpParent
->maGeometry
.nX
;
2070 maGeometry
.nY
+= mpParent
->maGeometry
.nY
;
2073 updateScreenNumber();
2074 if( bSized
&& ! bMoved
)
2075 CallCallback( SALEVENT_RESIZE
, NULL
);
2076 else if( bMoved
&& ! bSized
)
2077 CallCallback( SALEVENT_MOVE
, NULL
);
2079 CallCallback( SALEVENT_MOVERESIZE
, NULL
);
2081 // allow the external status window to reposition
2082 if (mbInputFocus
&& mpInputContext
!= NULL
)
2083 mpInputContext
->SetICFocus ( this );
2086 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2087 void X11SalFrame::Minimize()
2089 if( IsSysChildWindow() )
2092 if( SHOWSTATE_UNKNOWN
== nShowState_
|| SHOWSTATE_HIDDEN
== nShowState_
)
2094 stderr0( "X11SalFrame::Minimize on withdrawn window\n" );
2098 if( XIconifyWindow( GetXDisplay(),
2100 pDisplay_
->GetDefaultScreenNumber() ) )
2101 nShowState_
= SHOWSTATE_MINIMIZED
;
2104 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2105 void X11SalFrame::Maximize()
2107 if( IsSysChildWindow() )
2110 if( SHOWSTATE_MINIMIZED
== nShowState_
)
2112 GetDisplay()->getWMAdaptor()->frameIsMapping( this );
2113 XMapWindow( GetXDisplay(), GetShellWindow() );
2114 nShowState_
= SHOWSTATE_NORMAL
;
2117 pDisplay_
->getWMAdaptor()->maximizeFrame( this, true, true );
2120 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2121 void X11SalFrame::Restore()
2123 if( IsSysChildWindow() )
2126 if( SHOWSTATE_UNKNOWN
== nShowState_
|| SHOWSTATE_HIDDEN
== nShowState_
)
2128 stderr0( "X11SalFrame::Restore on withdrawn window\n" );
2132 if( SHOWSTATE_MINIMIZED
== nShowState_
)
2134 GetDisplay()->getWMAdaptor()->frameIsMapping( this );
2135 XMapWindow( GetXDisplay(), GetShellWindow() );
2136 nShowState_
= SHOWSTATE_NORMAL
;
2139 pDisplay_
->getWMAdaptor()->maximizeFrame( this, false, false );
2142 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2144 void X11SalFrame::SetScreenNumber( unsigned int nNewScreen
)
2146 if( nNewScreen
== maGeometry
.nScreenNumber
)
2149 if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 )
2151 if( nNewScreen
>= GetDisplay()->GetXineramaScreens().size() )
2154 Rectangle
aOldScreenRect( GetDisplay()->GetXineramaScreens()[maGeometry
.nScreenNumber
] );
2155 Rectangle
aNewScreenRect( GetDisplay()->GetXineramaScreens()[nNewScreen
] );
2156 bool bVisible
= bMapped_
;
2159 maGeometry
.nX
= aNewScreenRect
.Left() + (maGeometry
.nX
- aOldScreenRect
.Left());
2160 maGeometry
.nY
= aNewScreenRect
.Top() + (maGeometry
.nY
- aOldScreenRect
.Top());
2161 createNewWindow( None
, m_nScreen
);
2164 maGeometry
.nScreenNumber
= nNewScreen
;
2166 else if( sal_Int32(nNewScreen
) < GetDisplay()->GetScreenCount() )
2168 bool bVisible
= bMapped_
;
2171 createNewWindow( None
, nNewScreen
);
2174 maGeometry
.nScreenNumber
= nNewScreen
;
2178 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2180 void X11SalFrame::ShowFullScreen( BOOL bFullScreen
, sal_Int32 nScreen
)
2182 if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 )
2184 if( mbFullScreen
== (bool)bFullScreen
)
2188 maRestorePosSize
= Rectangle( Point( maGeometry
.nX
, maGeometry
.nY
),
2189 Size( maGeometry
.nWidth
, maGeometry
.nHeight
) );
2191 if( nScreen
< 0 || nScreen
>= static_cast<int>(GetDisplay()->GetXineramaScreens().size()) )
2192 aRect
= Rectangle( Point(0,0), GetDisplay()->GetScreenSize( m_nScreen
) );
2194 aRect
= GetDisplay()->GetXineramaScreens()[nScreen
];
2195 nStyle_
|= SAL_FRAME_STYLE_PARTIAL_FULLSCREEN
;
2196 bool bVisible
= bMapped_
;
2199 maGeometry
.nX
= aRect
.Left();
2200 maGeometry
.nY
= aRect
.Top();
2201 maGeometry
.nWidth
= aRect
.GetWidth();
2202 maGeometry
.nHeight
= aRect
.GetHeight();
2203 mbMaximizedHorz
= mbMaximizedVert
= false;
2204 createNewWindow( None
, m_nScreen
);
2205 GetDisplay()->getWMAdaptor()->enableAlwaysOnTop( this, true );
2207 // this would give additional intent to the window
2208 // manager to force the positioning of the window;
2209 // alas all other windows will be expunged from that
2210 // region, leaving us in a pity state afterwards
2211 Size aScreenSize
= pDisplay_
->GetScreenSize( m_nScreen
);
2212 pDisplay_
->getWMAdaptor()->setFrameStruts( this,
2213 aRect
.Left(), aRect
.Top(),
2214 aScreenSize
.Width() - aRect
.Right(),
2215 aScreenSize
.Height() - aRect
.Bottom(),
2216 aRect
.Left(), aRect
.Right(),
2217 aRect
.Top(), aRect
.Bottom(),
2218 aRect
.Left(), aRect
.Right(),
2219 aRect
.Top(), aRect
.Bottom()
2225 mbFullScreen
= true;
2229 mbFullScreen
= false;
2230 nStyle_
&= ~SAL_FRAME_STYLE_PARTIAL_FULLSCREEN
;
2231 bool bVisible
= bMapped_
;
2232 Rectangle aRect
= maRestorePosSize
;
2233 maRestorePosSize
= Rectangle();
2236 createNewWindow( None
, m_nScreen
);
2237 if( !aRect
.IsEmpty() )
2238 SetPosSize( aRect
.Left(), aRect
.Top(), aRect
.GetWidth(), aRect
.GetHeight(),
2239 SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
|
2240 SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
);
2247 if( nScreen
< 0 || nScreen
>= GetDisplay()->GetScreenCount() )
2248 nScreen
= m_nScreen
;
2249 if( nScreen
!= m_nScreen
)
2251 bool bVisible
= bMapped_
;
2253 pDisplay_
->getWMAdaptor()->showFullScreen( this, false );
2256 createNewWindow( None
, nScreen
);
2258 pDisplay_
->getWMAdaptor()->showFullScreen( this, true );
2262 if( mbFullScreen
== (bool)bFullScreen
)
2265 pDisplay_
->getWMAdaptor()->showFullScreen( this, bFullScreen
);
2266 if( IsOverrideRedirect()
2267 && WMSupportsFWS( GetXDisplay(), GetDisplay()->GetRootWindow( m_nScreen
) ) )
2269 AddFwsProtocols( GetXDisplay(), GetShellWindow() );
2270 RegisterFwsWindow( GetXDisplay(), GetShellWindow() );
2275 /* ---------------------------------------------------------------------
2276 the xautolock pseudo screen saver needs special treatment since it
2277 doesn't cooperate with XxxxScreenSaver settings
2278 ------------------------------------------------------------------- */
2281 IsRunningXAutoLock( Display
*p_display
, XLIB_Window a_window
)
2283 const char *p_atomname
= "XAUTOLOCK_SEMAPHORE_PID";
2286 // xautolock interns this atom
2287 a_pidatom
= XInternAtom( p_display
, p_atomname
, True
);
2288 if ( a_pidatom
== None
)
2293 unsigned long n_items
;
2294 unsigned long n_bytes_after
;
2297 // get pid of running xautolock
2298 XGetWindowProperty (p_display
, a_window
, a_pidatom
, 0L, 2L, False
,
2299 AnyPropertyType
, &a_type
, &n_format
, &n_items
, &n_bytes_after
,
2300 (unsigned char**) &p_pid
);
2304 if ( a_type
== XA_INTEGER
)
2306 // check if xautolock pid points to a running process
2307 if ( kill(n_pid
, 0) == -1 )
2316 /* definitions from xautolock.c (pl15) */
2317 #define XAUTOLOCK_DISABLE 1
2318 #define XAUTOLOCK_ENABLE 2
2321 MessageToXAutoLock( Display
*p_display
, int n_message
)
2323 const char *p_atomname
= "XAUTOLOCK_MESSAGE" ;
2325 XLIB_Window a_rootwindow
;
2327 a_rootwindow
= RootWindowOfScreen( ScreenOfDisplay(p_display
, 0) );
2328 if ( ! IsRunningXAutoLock(p_display
, a_rootwindow
) )
2330 // remove any pending messages
2331 a_messageatom
= XInternAtom( p_display
, p_atomname
, True
);
2332 if ( a_messageatom
!= None
)
2333 XDeleteProperty( p_display
, a_rootwindow
, a_messageatom
);
2337 a_messageatom
= XInternAtom( p_display
, p_atomname
, False
);
2338 XChangeProperty (p_display
, a_rootwindow
, a_messageatom
, XA_INTEGER
,
2339 8, PropModeReplace
, (unsigned char*)&n_message
, sizeof(n_message
) );
2344 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2345 void X11SalFrame::StartPresentation( BOOL bStart
)
2347 I18NStatus::get().show( !bStart
, I18NStatus::presentation
);
2349 MessageToXAutoLock( GetXDisplay(), XAUTOLOCK_DISABLE
);
2351 MessageToXAutoLock( GetXDisplay(), XAUTOLOCK_ENABLE
);
2353 if( ! bStart
&& hPresentationWindow
!= None
)
2354 doReparentPresentationDialogues( GetDisplay() );
2355 hPresentationWindow
= (bStart
&& IsOverrideRedirect() ) ? GetWindow() : None
;
2358 // needs static here to save DPMS settings
2360 static bool DPMSExtensionAvailable
=
2362 (DPMSQueryExtension(GetXDisplay(), &dummy
, &dummy
) != 0);
2363 static XLIB_BOOL DPMSEnabled
= false;
2366 bool DPMSEnabled
= false;
2368 #define CARD16 unsigned short
2370 static CARD16 dpms_standby_timeout
=0;
2371 static CARD16 dpms_suspend_timeout
=0;
2372 static CARD16 dpms_off_timeout
=0;
2375 if( bStart
|| nScreenSaversTimeout_
|| DPMSEnabled
)
2377 if( hPresentationWindow
)
2379 /* #i10559# workaround for WindowMaker: try to restore
2380 * current focus after presentation window is gone
2383 XGetInputFocus( GetXDisplay(), &hPresFocusWindow
, &revert_to
);
2385 int timeout
, interval
, prefer_blanking
, allow_exposures
;
2386 XGetScreenSaver( GetXDisplay(),
2393 // get the DPMS state right before the start
2394 if (DPMSExtensionAvailable
)
2397 CARD16 state
; // card16 is defined in Xdm.h
2398 DPMSInfo( GetXDisplay(),
2403 if( bStart
) // start show
2407 nScreenSaversTimeout_
= timeout
;
2408 XResetScreenSaver( GetXDisplay() );
2409 XSetScreenSaver( GetXDisplay(),
2418 if ( DPMSExtensionAvailable
)
2420 DPMSGetTimeouts( GetXDisplay(),
2421 &dpms_standby_timeout
,
2422 &dpms_suspend_timeout
,
2424 DPMSSetTimeouts(GetXDisplay(), 0,0,0);
2429 else // if( !bStart ) // end of show
2431 if( nScreenSaversTimeout_
)
2433 XSetScreenSaver( GetXDisplay(),
2434 nScreenSaversTimeout_
,
2438 nScreenSaversTimeout_
= 0;
2443 if ( DPMSExtensionAvailable
)
2446 DPMSSetTimeouts(GetXDisplay(), dpms_standby_timeout
,
2447 dpms_suspend_timeout
, dpms_off_timeout
);
2456 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2457 void X11SalFrame::SetPointer( PointerStyle ePointerStyle
)
2459 hCursor_
= pDisplay_
->GetPointer( ePointerStyle
);
2460 XDefineCursor( GetXDisplay(), GetWindow(), hCursor_
);
2462 if( IsCaptured() || nVisibleFloats
> 0 )
2463 XChangeActivePointerGrab( GetXDisplay(),
2464 PointerMotionMask
|ButtonPressMask
|ButtonReleaseMask
,
2469 void X11SalFrame::SetPointerPos(long nX
, long nY
)
2471 /* #87921# when the application tries to center the mouse in the dialog the
2472 * window isn't mapped already. So use coordinates relative to the root window.
2474 unsigned int nWindowLeft
= maGeometry
.nX
+ nX
;
2475 unsigned int nWindowTop
= maGeometry
.nY
+ nY
;
2477 XWarpPointer( GetXDisplay(), None
, pDisplay_
->GetRootWindow( pDisplay_
->GetDefaultScreenNumber() ),
2478 0, 0, 0, 0, nWindowLeft
, nWindowTop
);
2481 // delay handling of extended text input
2482 #if !defined(__synchronous_extinput__)
2484 X11SalFrame::PostExtTextEvent (sal_uInt16 nExtTextEventType
, void *pExtTextEvent
)
2486 XLIB_Window nFocusWindow
= GetWindow();
2487 Atom nEventAtom
= GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::SAL_EXTTEXTEVENT
);
2490 aEvent
.xclient
.type
= ClientMessage
;
2491 aEvent
.xclient
.serial
= 0;
2492 aEvent
.xclient
.send_event
= True
;
2493 aEvent
.xclient
.display
= GetXDisplay();
2494 aEvent
.xclient
.window
= nFocusWindow
;
2495 aEvent
.xclient
.message_type
= nEventAtom
;
2496 aEvent
.xclient
.format
= 32;
2498 #if SAL_TYPES_SIZEOFLONG > 4
2499 aEvent
.xclient
.data
.l
[0] = (sal_uInt32
)((long)pExtTextEvent
& 0xffffffff);
2500 aEvent
.xclient
.data
.l
[1] = (sal_uInt32
)((long)pExtTextEvent
>> 32);
2502 aEvent
.xclient
.data
.l
[0] = (sal_uInt32
)((long)pExtTextEvent
);
2503 aEvent
.xclient
.data
.l
[1] = 0;
2505 aEvent
.xclient
.data
.l
[2] = (sal_uInt32
)nExtTextEventType
;
2506 aEvent
.xclient
.data
.l
[3] = 0;
2507 aEvent
.xclient
.data
.l
[4] = 0;
2509 XPutBackEvent( GetXDisplay(), &aEvent
);
2513 X11SalFrame::HandleExtTextEvent (XClientMessageEvent
*pEvent
)
2515 #if SAL_TYPES_SIZEOFLONG > 4
2516 void* pExtTextEvent
= (void*)( (pEvent
->data
.l
[0] & 0xffffffff)
2517 | (pEvent
->data
.l
[1] << 32) );
2519 void* pExtTextEvent
= (void*)(pEvent
->data
.l
[0]);
2521 sal_uInt16 nExtTextEventType
= sal_uInt16(pEvent
->data
.l
[2]);
2523 CallCallback(nExtTextEventType
, pExtTextEvent
);
2525 switch (nExtTextEventType
)
2527 case SALEVENT_ENDEXTTEXTINPUT
:
2530 case SALEVENT_EXTTEXTINPUT
:
2535 fprintf(stderr
, "X11SalFrame::HandleExtTextEvent: invalid extended input\n");
2538 #endif /* defined(__synchronous_extinput__) */
2541 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2542 BOOL
X11SalFrame::PostEvent( void *pData
)
2544 GetDisplay()->SendInternalEvent( this, pData
);
2549 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2550 void X11SalFrame::SetTitle( const XubString
& rTitle
)
2552 if( ! ( IsChildWindow() || (nStyle_
& SAL_FRAME_STYLE_FLOAT
) ) )
2555 GetDisplay()->getWMAdaptor()->setWMName( this, rTitle
);
2559 // -----------------------------------------------------------------------
2561 void X11SalFrame::Flush()
2563 XFlush( GetDisplay()->GetDisplay() );
2566 // -----------------------------------------------------------------------
2568 void X11SalFrame::Sync()
2570 XSync( GetDisplay()->GetDisplay(), False
);
2574 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2576 // -----------------------------------------------------------------------
2578 void X11SalFrame::SetInputContext( SalInputContext
* pContext
)
2580 if (pContext
== NULL
)
2583 // 1. We should create an input context for this frame
2584 // only when SAL_INPUTCONTEXT_TEXT is set.
2586 if (!(pContext
->mnOptions
& SAL_INPUTCONTEXT_TEXT
))
2588 if( mpInputContext
)
2589 mpInputContext
->Unmap( this );
2593 // 2. We should use on-the-spot inputstyle
2594 // only when SAL_INPUTCONTEXT_EXTTEXTINPUT is set.
2596 if (mpInputContext
== NULL
)
2598 I18NStatus
& rStatus( I18NStatus::get() );
2599 rStatus
.setParent( this );
2600 mpInputContext
= new SalI18N_InputContext( this );
2601 if (mpInputContext
->UseContext())
2603 mpInputContext
->ExtendEventMask( GetShellWindow() );
2604 if (pContext
->mnOptions
& SAL_INPUTCONTEXT_CHANGELANGUAGE
)
2605 mpInputContext
->SetLanguage(pContext
->meLanguage
);
2607 mpInputContext
->SetICFocus( this );
2611 mpInputContext
->Map( this );
2615 // -----------------------------------------------------------------------
2617 void X11SalFrame::EndExtTextInput( USHORT nFlags
)
2619 if (mpInputContext
!= NULL
)
2620 mpInputContext
->EndExtTextInput( nFlags
);
2623 // -----------------------------------------------------------------------
2625 XubString
X11SalFrame::GetKeyName( USHORT nKeyCode
)
2627 return GetDisplay()->GetKeyName( nKeyCode
);
2630 XubString
X11SalFrame::GetSymbolKeyName( const XubString
&, USHORT nKeyCode
)
2632 return GetKeyName( nKeyCode
);
2635 BOOL
X11SalFrame::MapUnicodeToKeyCode( sal_Unicode
, LanguageType
, KeyCode
& )
2637 // not supported yet
2641 LanguageType
X11SalFrame::GetInputLanguage()
2643 // could be improved by checking unicode ranges of the last input
2644 return LANGUAGE_DONTKNOW
;
2648 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2650 inline Color
getColorFromLong( long nColor
)
2652 return Color( (nColor
& 0xff), (nColor
& 0xff00)>>8, (nColor
& 0xff0000)>>16);
2655 void X11SalFrame::UpdateSettings( AllSettings
& rSettings
)
2658 DtIntegrator
* pIntegrator
= GetDisplay()->getDtIntegrator();
2659 #if OSL_DEBUG_LEVEL > 1
2660 fprintf( stderr
, "DtIntegrator: %d\n", pIntegrator
? pIntegrator
->GetDtType() : -1 );
2663 pIntegrator
->GetSystemLook( rSettings
);
2666 void X11SalFrame::CaptureMouse( BOOL bCapture
)
2668 nCaptured_
= pDisplay_
->CaptureMouse( bCapture
? this : NULL
);
2671 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2673 void X11SalFrame::SetParent( SalFrame
* pNewParent
)
2675 if( mpParent
!= pNewParent
)
2678 mpParent
->maChildren
.remove( this );
2680 mpParent
= static_cast<X11SalFrame
*>(pNewParent
);
2681 mpParent
->maChildren
.push_back( this );
2682 if( mpParent
->m_nScreen
!= m_nScreen
)
2683 createNewWindow( None
, mpParent
->m_nScreen
);
2684 GetDisplay()->getWMAdaptor()->changeReferenceFrame( this, mpParent
);
2688 SalFrame
* X11SalFrame::GetParent() const
2693 void X11SalFrame::createNewWindow( XLIB_Window aNewParent
, int nScreen
)
2695 bool bWasVisible
= bMapped_
;
2699 if( nScreen
< 0 || nScreen
>= GetDisplay()->GetScreenCount() )
2700 nScreen
= m_nScreen
;
2702 SystemParentData aParentData
;
2703 aParentData
.aWindow
= aNewParent
;
2704 aParentData
.bXEmbedSupport
= (aNewParent
!= None
&& m_bXEmbed
); // caution: this is guesswork
2705 if( aNewParent
== None
)
2707 aNewParent
= GetDisplay()->GetRootWindow(nScreen
);
2708 aParentData
.aWindow
= None
;
2713 // is new parent a root window ?
2714 Display
* pDisp
= GetDisplay()->GetDisplay();
2715 int nScreens
= GetDisplay()->GetScreenCount();
2716 for( int i
= 0; i
< nScreens
; i
++ )
2718 if( aNewParent
== RootWindow( pDisp
, i
) )
2721 aParentData
.aWindow
= None
;
2728 // first deinit frame
2729 if( mpInputContext
)
2731 mpInputContext
->UnsetICFocus( this );
2732 mpInputContext
->Unmap( this );
2734 if( GetWindow() == hPresentationWindow
)
2736 hPresentationWindow
= None
;
2737 doReparentPresentationDialogues( GetDisplay() );
2739 XDestroyWindow( GetXDisplay(), mhWindow
);
2742 passOnSaveYourSelf();
2744 // now init with new parent again
2745 if ( aParentData
.aWindow
!= None
)
2746 Init( nStyle_
| SAL_FRAME_STYLE_PLUG
, nScreen
, &aParentData
);
2748 Init( nStyle_
& ~SAL_FRAME_STYLE_PLUG
, nScreen
, NULL
, true );
2750 // update graphics if necessary
2753 if( m_aTitle
.Len() )
2754 SetTitle( m_aTitle
);
2758 if( mpParent
->m_nScreen
!= m_nScreen
)
2761 pDisplay_
->getWMAdaptor()->changeReferenceFrame( this, mpParent
);
2767 std::list
< X11SalFrame
* > aChildren
= maChildren
;
2768 for( std::list
< X11SalFrame
* >::iterator it
= aChildren
.begin(); it
!= aChildren
.end(); ++it
)
2769 (*it
)->createNewWindow( None
, m_nScreen
);
2771 // FIXME: SalObjects
2774 bool X11SalFrame::SetPluginParent( SystemParentData
* pNewParent
)
2776 if( pNewParent
->nSize
>= sizeof(SystemParentData
) )
2777 m_bXEmbed
= pNewParent
->aWindow
!= None
&& pNewParent
->bXEmbedSupport
;
2778 createNewWindow( pNewParent
? pNewParent
->aWindow
: None
);
2784 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2785 void X11SalFrame::Beep( SoundType eSoundType
) // not fully suported
2787 switch( eSoundType
)
2791 GetDisplay()->Beep();
2794 // Excessive beeping averted
2800 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2801 static USHORT
sal_GetCode( int state
)
2805 if( state
& Button1Mask
)
2806 nCode
|= MOUSE_LEFT
;
2807 if( state
& Button2Mask
)
2808 nCode
|= MOUSE_MIDDLE
;
2809 if( state
& Button3Mask
)
2810 nCode
|= MOUSE_RIGHT
;
2812 if( state
& ShiftMask
)
2814 if( state
& ControlMask
)
2816 if( state
& Mod1Mask
)
2819 // Map Meta/Super modifier to MOD3 on all Unix systems
2821 if( (state
& Mod3Mask
) )
2827 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2829 SalFrame::SalPointerState
X11SalFrame::GetPointerState()
2831 SalPointerState aState
;
2832 XLIB_Window aRoot
, aChild
;
2834 unsigned int nMask
= 0;
2835 XQueryPointer( GetXDisplay(),
2844 aState
.maPos
= Point(wx
, wy
);
2845 aState
.mnState
= sal_GetCode( nMask
);
2849 SalFrame::SalIndicatorState
X11SalFrame::GetIndicatorState()
2851 SalIndicatorState aState
;
2852 aState
.mnState
= GetX11SalData()->GetDisplay()->GetIndicatorState();
2856 void X11SalFrame::SimulateKeyPress( USHORT nKeyCode
)
2858 GetX11SalData()->GetDisplay()->SimulateKeyPress(nKeyCode
);
2861 long X11SalFrame::HandleMouseEvent( XEvent
*pEvent
)
2863 SalMouseEvent aMouseEvt
;
2865 bool bClosePopups
= false;
2867 if( nVisibleFloats
&& pEvent
->type
== EnterNotify
)
2870 // Solaris X86: clicking the right button on a two-button mouse
2871 // generates a button2 event not a button3 event
2872 if (pDisplay_
->GetProperties() & PROPERTY_SUPPORT_3ButtonMouse
)
2874 switch (pEvent
->type
)
2878 if ( pEvent
->xcrossing
.state
& Button2Mask
)
2880 pEvent
->xcrossing
.state
&= ~Button2Mask
;
2881 pEvent
->xcrossing
.state
|= Button3Mask
;
2886 if ( pEvent
->xmotion
.state
& Button2Mask
)
2888 pEvent
->xmotion
.state
&= ~Button2Mask
;
2889 pEvent
->xmotion
.state
|= Button3Mask
;
2894 if ( Button2
== pEvent
->xbutton
.button
)
2896 pEvent
->xbutton
.state
&= ~Button2Mask
;
2897 pEvent
->xbutton
.state
|= Button3Mask
;
2898 pEvent
->xbutton
.button
= Button3
;
2905 if( LeaveNotify
== pEvent
->type
|| EnterNotify
== pEvent
->type
)
2910 * some WMs (and/or) applications have a passive grab on
2911 * mouse buttons (XGrabButton). This leads to enter/leave notifies
2912 * with mouse buttons pressed in the state mask before the actual
2913 * ButtonPress event gets dispatched. But EnterNotify
2914 * is reported in vcl as MouseMove event. Some office code
2915 * decides that a pressed button in a MouseMove belongs to
2916 * a drag operation which leads to doing things differently.
2919 * ignore Enter/LeaveNotify resulting from grabs so that
2920 * help windows do not disappear just after appearing
2922 * hopefully this workaround will not break anything.
2924 if( pEvent
->xcrossing
.mode
== NotifyGrab
|| pEvent
->xcrossing
.mode
== NotifyUngrab
)
2927 aMouseEvt
.mnX
= pEvent
->xcrossing
.x
;
2928 aMouseEvt
.mnY
= pEvent
->xcrossing
.y
;
2929 aMouseEvt
.mnTime
= pEvent
->xcrossing
.time
;
2930 aMouseEvt
.mnCode
= sal_GetCode( pEvent
->xcrossing
.state
);
2931 aMouseEvt
.mnButton
= 0;
2933 nEvent
= LeaveNotify
== pEvent
->type
2934 ? SALEVENT_MOUSELEAVE
2935 : SALEVENT_MOUSEMOVE
;
2937 else if( pEvent
->type
== MotionNotify
)
2939 aMouseEvt
.mnX
= pEvent
->xmotion
.x
;
2940 aMouseEvt
.mnY
= pEvent
->xmotion
.y
;
2941 aMouseEvt
.mnTime
= pEvent
->xmotion
.time
;
2942 aMouseEvt
.mnCode
= sal_GetCode( pEvent
->xmotion
.state
);
2944 aMouseEvt
.mnButton
= 0;
2946 nEvent
= SALEVENT_MOUSEMOVE
;
2947 if( nVisibleFloats
> 0 && mpParent
)
2949 XLIB_Cursor aCursor
= mpParent
->GetCursor();
2950 if( pEvent
->xmotion
.x
>= 0 && pEvent
->xmotion
.x
< (int)maGeometry
.nWidth
&&
2951 pEvent
->xmotion
.y
>= 0 && pEvent
->xmotion
.y
< (int)maGeometry
.nHeight
)
2954 XChangeActivePointerGrab( GetXDisplay(),
2955 PointerMotionMask
|ButtonPressMask
|ButtonReleaseMask
,
2962 // let mouse events reach the correct window
2963 if( nVisibleFloats
< 1 )
2965 if( ! (nStyle_
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) )
2966 XUngrabPointer( GetXDisplay(), CurrentTime
);
2968 else if( pEvent
->type
== ButtonPress
)
2970 // see if the user clicks outside all of the floats
2971 // if yes release the grab
2972 bool bInside
= false;
2973 const std::list
< SalFrame
* >& rFrames
= GetDisplay()->getFrames();
2974 for( std::list
< SalFrame
* >::const_iterator it
= rFrames
.begin(); it
!= rFrames
.end(); ++it
)
2976 const X11SalFrame
* pFrame
= static_cast< const X11SalFrame
* >(*it
);
2977 if( pFrame
->IsFloatGrabWindow() &&
2979 pEvent
->xbutton
.x_root
>= pFrame
->maGeometry
.nX
&&
2980 pEvent
->xbutton
.x_root
< pFrame
->maGeometry
.nX
+ (int)pFrame
->maGeometry
.nWidth
&&
2981 pEvent
->xbutton
.y_root
>= pFrame
->maGeometry
.nY
&&
2982 pEvent
->xbutton
.y_root
< pFrame
->maGeometry
.nY
+ (int)pFrame
->maGeometry
.nHeight
)
2990 // need not take care of the XUngrabPointer in Show( FALSE )
2991 // because XUngrabPointer does not produce errors if pointer
2993 XUngrabPointer( GetXDisplay(), CurrentTime
);
2994 bClosePopups
= true;
2996 /* #i15246# only close popups if pointer is outside all our frames
2997 * cannot use our own geometry data here because stacking
2998 * is unknown (the above case implicitly assumes
2999 * that floats are on top which should be true)
3001 XLIB_Window aRoot
, aChild
;
3002 int root_x
, root_y
, win_x
, win_y
;
3003 unsigned int mask_return
;
3004 if( XQueryPointer( GetXDisplay(),
3005 GetDisplay()->GetRootWindow( m_nScreen
),
3010 && aChild
// pointer may not be in any child
3013 for( std::list
< SalFrame
* >::const_iterator it
= rFrames
.begin(); it
!= rFrames
.end(); ++it
)
3015 const X11SalFrame
* pFrame
= static_cast< const X11SalFrame
* >(*it
);
3016 if( ! pFrame
->IsFloatGrabWindow()
3017 && ( pFrame
->GetWindow() == aChild
||
3018 pFrame
->GetShellWindow() == aChild
||
3019 pFrame
->GetStackingWindow() == aChild
)
3022 // #i63638# check that pointer is inside window, not
3023 // only inside stacking window
3024 if( root_x
>= pFrame
->maGeometry
.nX
&& root_x
< sal::static_int_cast
< int >(pFrame
->maGeometry
.nX
+pFrame
->maGeometry
.nWidth
) &&
3025 root_y
>= pFrame
->maGeometry
.nY
&& root_y
< sal::static_int_cast
< int >(pFrame
->maGeometry
.nX
+pFrame
->maGeometry
.nHeight
) )
3027 bClosePopups
= false;
3036 if( m_bXEmbed
&& pEvent
->xbutton
.button
== Button1
)
3037 askForXEmbedFocus( pEvent
->xbutton
.time
);
3039 if( pEvent
->xbutton
.button
== Button1
||
3040 pEvent
->xbutton
.button
== Button2
||
3041 pEvent
->xbutton
.button
== Button3
)
3043 aMouseEvt
.mnX
= pEvent
->xbutton
.x
;
3044 aMouseEvt
.mnY
= pEvent
->xbutton
.y
;
3045 aMouseEvt
.mnTime
= pEvent
->xbutton
.time
;
3046 aMouseEvt
.mnCode
= sal_GetCode( pEvent
->xbutton
.state
);
3048 if( Button1
== pEvent
->xbutton
.button
)
3049 aMouseEvt
.mnButton
= MOUSE_LEFT
;
3050 else if( Button2
== pEvent
->xbutton
.button
)
3051 aMouseEvt
.mnButton
= MOUSE_MIDDLE
;
3052 else if( Button3
== pEvent
->xbutton
.button
)
3053 aMouseEvt
.mnButton
= MOUSE_RIGHT
;
3055 nEvent
= ButtonPress
== pEvent
->type
3056 ? SALEVENT_MOUSEBUTTONDOWN
3057 : SALEVENT_MOUSEBUTTONUP
;
3059 else if( pEvent
->xbutton
.button
== Button4
||
3060 pEvent
->xbutton
.button
== Button5
||
3061 pEvent
->xbutton
.button
== Button6
||
3062 pEvent
->xbutton
.button
== Button7
)
3064 const bool bIncrement(
3065 pEvent
->xbutton
.button
== Button4
||
3066 pEvent
->xbutton
.button
== Button6
);
3068 pEvent
->xbutton
.button
== Button6
||
3069 pEvent
->xbutton
.button
== Button7
);
3071 if( pEvent
->type
== ButtonRelease
)
3074 static ULONG nLines
= 0;
3077 char* pEnv
= getenv( "SAL_WHEELLINES" );
3078 nLines
= pEnv
? atoi( pEnv
) : 3;
3080 nLines
= SAL_WHEELMOUSE_EVENT_PAGESCROLL
;
3083 SalWheelMouseEvent aWheelEvt
;
3084 aWheelEvt
.mnTime
= pEvent
->xbutton
.time
;
3085 aWheelEvt
.mnX
= pEvent
->xbutton
.x
;
3086 aWheelEvt
.mnY
= pEvent
->xbutton
.y
;
3087 aWheelEvt
.mnDelta
= bIncrement
? 120 : -120;
3088 aWheelEvt
.mnNotchDelta
= bIncrement
? 1 : -1;
3089 aWheelEvt
.mnScrollLines
= nLines
;
3090 aWheelEvt
.mnCode
= sal_GetCode( pEvent
->xbutton
.state
);
3091 aWheelEvt
.mbHorz
= bHoriz
;
3093 nEvent
= SALEVENT_WHEELMOUSE
;
3095 // --- RTL --- (mirror mouse pos)
3096 if( Application::GetSettings().GetLayoutRTL() )
3097 aWheelEvt
.mnX
= nWidth_
-1-aWheelEvt
.mnX
;
3098 return CallCallback( nEvent
, &aWheelEvt
);
3103 if( nEvent
== SALEVENT_MOUSELEAVE
3104 || ( aMouseEvt
.mnX
< nWidth_
&& aMouseEvt
.mnX
> -1 &&
3105 aMouseEvt
.mnY
< nHeight_
&& aMouseEvt
.mnY
> -1 )
3106 || pDisplay_
->MouseCaptured( this )
3109 // --- RTL --- (mirror mouse pos)
3110 if( Application::GetSettings().GetLayoutRTL() )
3111 aMouseEvt
.mnX
= nWidth_
-1-aMouseEvt
.mnX
;
3112 nRet
= CallCallback( nEvent
, &aMouseEvt
);
3117 /* #108213# close popups after dispatching the event outside the popup;
3118 * applications do weird things.
3120 ImplSVData
* pSVData
= ImplGetSVData();
3121 if ( pSVData
->maWinData
.mpFirstFloat
)
3123 static const char* pEnv
= getenv( "SAL_FLOATWIN_NOAPPFOCUSCLOSE" );
3124 if ( !(pSVData
->maWinData
.mpFirstFloat
->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE
) && !(pEnv
&& *pEnv
) )
3125 pSVData
->maWinData
.mpFirstFloat
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
| FLOATWIN_POPUPMODEEND_CLOSEALL
);
3132 // F10 means either KEY_F10 or KEY_MENU, which has to be decided
3133 // in the independent part.
3137 sal_Unicode nCharCode
;
3138 KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {}
3139 KeyAlternate( USHORT nKey
, sal_Unicode nChar
= 0 ) : nKeyCode( nKey
), nCharCode( nChar
) {}
3143 GetAlternateKeyCode( const USHORT nKeyCode
)
3145 KeyAlternate aAlternate
;
3149 case KEY_F10
: aAlternate
= KeyAlternate( KEY_MENU
);break;
3150 case KEY_F24
: aAlternate
= KeyAlternate( KEY_SUBTRACT
, '-' );break;
3156 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3157 long X11SalFrame::HandleKeyEvent( XKeyEvent
*pEvent
)
3160 KeySym nUnmodifiedKeySym
;
3162 unsigned char *pPrintable
= (unsigned char*)alloca( nLen
);
3164 // singlebyte code composed by input method, the new default
3165 if (mpInputContext
!= NULL
&& mpInputContext
->UseContext())
3167 // returns a keysym as well as the pPrintable (in system encoding)
3168 // printable may be empty.
3170 nKeySym
= pDisplay_
->GetKeySym( pEvent
, pPrintable
, &nLen
,
3172 &nStatus
, mpInputContext
->GetContext() );
3173 if ( nStatus
== XBufferOverflow
)
3176 pPrintable
= (unsigned char*)alloca( nLen
);
3177 nKeySym
= pDisplay_
->GetKeySym( pEvent
, pPrintable
, &nLen
,
3179 &nStatus
, mpInputContext
->GetContext() );
3184 // fallback, this should never ever be called
3186 nKeySym
= pDisplay_
->GetKeySym( pEvent
, pPrintable
, &nLen
, &nUnmodifiedKeySym
, &nStatus
);
3189 SalKeyEvent aKeyEvt
;
3191 USHORT nModCode
= 0;
3194 if( pEvent
->state
& ShiftMask
)
3195 nModCode
|= KEY_SHIFT
;
3196 if( pEvent
->state
& ControlMask
)
3197 nModCode
|= KEY_MOD1
;
3198 if( pEvent
->state
& Mod1Mask
)
3199 nModCode
|= KEY_MOD2
;
3201 if( nKeySym
== XK_Shift_L
|| nKeySym
== XK_Shift_R
3202 || nKeySym
== XK_Control_L
|| nKeySym
== XK_Control_R
3203 || nKeySym
== XK_Alt_L
|| nKeySym
== XK_Alt_R
3204 || nKeySym
== XK_Meta_L
|| nKeySym
== XK_Meta_R
3205 || nKeySym
== XK_Super_L
|| nKeySym
== XK_Super_R
)
3207 SalKeyModEvent aModEvt
;
3208 aModEvt
.mnModKeyCode
= 0;
3209 if( pEvent
->type
== XLIB_KeyPress
&& mnExtKeyMod
== 0 )
3210 mbSendExtKeyModChange
= true;
3211 else if( pEvent
->type
== KeyRelease
&& mbSendExtKeyModChange
)
3213 aModEvt
.mnModKeyCode
= mnExtKeyMod
;
3217 // pressing just the ctrl key leads to a keysym of XK_Control but
3218 // the event state does not contain ControlMask. In the release
3219 // event its the other way round: it does contain the Control mask.
3220 // The modifier mode therefore has to be adapted manually.
3221 USHORT nExtModMask
= 0;
3222 USHORT nModMask
= 0;
3226 nExtModMask
= MODKEY_LMOD1
;
3227 nModMask
= KEY_MOD1
;
3230 nExtModMask
= MODKEY_RMOD1
;
3231 nModMask
= KEY_MOD1
;
3234 nExtModMask
= MODKEY_LMOD2
;
3235 nModMask
= KEY_MOD2
;
3238 nExtModMask
= MODKEY_RMOD2
;
3239 nModMask
= KEY_MOD2
;
3242 nExtModMask
= MODKEY_LSHIFT
;
3243 nModMask
= KEY_SHIFT
;
3246 nExtModMask
= MODKEY_RSHIFT
;
3247 nModMask
= KEY_SHIFT
;
3249 // Map Meta/Super keys to MOD3 modifier on all Unix systems
3253 nExtModMask
= MODKEY_LMOD3
;
3254 nModMask
= KEY_MOD3
;
3258 nExtModMask
= MODKEY_RMOD3
;
3259 nModMask
= KEY_MOD3
;
3262 if( pEvent
->type
== KeyRelease
)
3264 nModCode
&= ~nModMask
;
3265 mnExtKeyMod
&= ~nExtModMask
;
3269 nModCode
|= nModMask
;
3270 mnExtKeyMod
|= nExtModMask
;
3273 aModEvt
.mnCode
= nModCode
;
3274 aModEvt
.mnTime
= pEvent
->time
;
3276 int nRet
= CallCallback( SALEVENT_KEYMODCHANGE
, &aModEvt
);
3279 if ( ( (nKeySym
== XK_Alt_L
) || (nKeySym
== XK_Alt_R
) ) &&
3280 ( (nModCode
& ~(KEY_MOD3
|KEY_MOD2
)) == 0 ) )
3282 if( pEvent
->type
== XLIB_KeyPress
)
3284 else if( mbKeyMenu
)
3286 // simulate KEY_MENU
3287 aKeyEvt
.mnCode
= KEY_MENU
| nModCode
;
3288 aKeyEvt
.mnRepeat
= 0;
3289 aKeyEvt
.mnTime
= pEvent
->time
;
3290 aKeyEvt
.mnCharCode
= 0;
3291 nRet
= CallCallback( SALEVENT_KEYINPUT
, &aKeyEvt
);
3292 nRet
= CallCallback( SALEVENT_KEYUP
, &aKeyEvt
);
3300 mbSendExtKeyModChange
= mbKeyMenu
= false;
3302 // try to figure out the vcl code for the keysym
3303 // #i52338# use the unmodified KeySym if there is none for the real KeySym
3304 // because the independent part has only keycodes for unshifted keys
3305 nKeyCode
= pDisplay_
->GetKeyCode( nKeySym
, &aDummy
);
3307 nKeyCode
= pDisplay_
->GetKeyCode( nUnmodifiedKeySym
, &aDummy
);
3309 // try to figure out a printable if XmbLookupString returns only a keysym
3310 // and NOT a printable. Do not store it in pPrintable[0] since it is expected to
3311 // be in system encoding, not unicode.
3312 // #i8988##, if KeySym and printable look equally promising then prefer KeySym
3313 // the printable is bound to the encoding so the KeySym might contain more
3314 // information (in et_EE locale: "Compose + Z + <" delivers "," in printable and
3315 // (the desired) Zcaron in KeySym
3316 sal_Unicode nKeyString
= 0x0;
3318 || ((nLen
== 1) && (nKeySym
> 0)) )
3319 nKeyString
= KeysymToUnicode (nKeySym
);
3320 // if we have nothing we give up
3321 if( !nKeyCode
&& !nLen
&& !nKeyString
)
3324 rtl_TextEncoding nEncoding
;
3326 if (mpInputContext
!= NULL
&& mpInputContext
->IsMultiLingual() )
3327 nEncoding
= RTL_TEXTENCODING_UTF8
;
3329 nEncoding
= osl_getThreadTextEncoding();
3331 sal_Unicode
*pBuffer
;
3332 sal_Unicode
*pString
;
3333 sal_Size nBufferSize
= nLen
* 2;
3335 pBuffer
= (sal_Unicode
*) malloc( nBufferSize
+ 2 );
3338 if (nKeyString
!= 0)
3340 pString
= &nKeyString
;
3344 if (nLen
> 0 && nEncoding
!= RTL_TEXTENCODING_UNICODE
)
3346 // create text converter
3347 rtl_TextToUnicodeConverter aConverter
=
3348 rtl_createTextToUnicodeConverter( nEncoding
);
3349 rtl_TextToUnicodeContext aContext
=
3350 rtl_createTextToUnicodeContext( aConverter
);
3352 sal_uInt32 nConversionInfo
;
3353 sal_Size nConvertedChars
;
3355 // convert to single byte text stream
3356 nSize
= rtl_convertTextToUnicode(
3357 aConverter
, aContext
,
3358 (char*)pPrintable
, nLen
,
3359 pBuffer
, nBufferSize
,
3360 RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE
|
3361 RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE
,
3362 &nConversionInfo
, &nConvertedChars
);
3364 // destroy converter
3365 rtl_destroyTextToUnicodeContext( aConverter
, aContext
);
3366 rtl_destroyTextToUnicodeConverter( aConverter
);
3371 if (nLen
> 0 /* nEncoding == RTL_TEXTENCODING_UNICODE */)
3373 pString
= (sal_Unicode
*)pPrintable
;
3382 DeletionListener
aDeleteWatch( this );
3384 if ( mpInputContext
!= NULL
3385 && mpInputContext
->UseContext()
3386 && KeyRelease
!= pEvent
->type
3388 || (nSize
> 0 && mpInputContext
->IsPreeditMode())) )
3390 mpInputContext
->CommitKeyEvent(pString
, nSize
);
3393 // normal single character keyinput
3395 aKeyEvt
.mnCode
= nKeyCode
| nModCode
;
3396 aKeyEvt
.mnRepeat
= 0;
3397 aKeyEvt
.mnTime
= pEvent
->time
;
3398 aKeyEvt
.mnCharCode
= pString
[ 0 ];
3400 if( KeyRelease
== pEvent
->type
)
3402 CallCallback( SALEVENT_KEYUP
, &aKeyEvt
);
3406 if ( ! CallCallback(SALEVENT_KEYINPUT
, &aKeyEvt
) )
3408 // independent layer doesnt want to handle key-event, so check
3409 // whether the keycode may have an alternate meaning
3410 KeyAlternate aAlternate
= GetAlternateKeyCode( nKeyCode
);
3411 if ( aAlternate
.nKeyCode
!= 0 )
3413 aKeyEvt
.mnCode
= aAlternate
.nKeyCode
| nModCode
;
3414 if( aAlternate
.nCharCode
)
3415 aKeyEvt
.mnCharCode
= aAlternate
.nCharCode
;
3416 CallCallback(SALEVENT_KEYINPUT
, &aKeyEvt
);
3423 // update the spot location for PreeditPosition IME style
3425 if (! aDeleteWatch
.isDeleted())
3427 if (mpInputContext
!= NULL
&& mpInputContext
->UseContext())
3428 mpInputContext
->UpdateSpotLocation();
3436 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3437 long X11SalFrame::HandleFocusEvent( XFocusChangeEvent
*pEvent
)
3439 // #107739# ReflectionX in Windows mode changes focus while mouse is grabbed
3440 if( nVisibleFloats
> 0 && GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii( "ReflectionX Windows" ) )
3443 /* #55691# ignore focusout resulting from keyboard grabs
3444 * we do not grab it and are not interested when
3445 * someone else does CDE e.g. does a XGrabKey on arrow keys
3446 * #73179# handle focus events with mode NotifyWhileGrabbed
3447 * because with CDE alt-tab focus changing we do not get
3448 * normal focus events
3449 * #71791# cast focus event to the input context, otherwise the
3450 * status window does not follow the application frame
3453 if ( mpInputContext
!= NULL
)
3455 if( FocusIn
== pEvent
->type
)
3456 mpInputContext
->SetICFocus( this );
3460 * do not unset the IC focuse here because would kill
3461 * a lookup choice windows that might have the focus now
3462 * mpInputContext->UnsetICFocus( this );
3464 I18NStatus::get().show( false, I18NStatus::focus
);
3469 if ( pEvent
->mode
== NotifyNormal
|| pEvent
->mode
== NotifyWhileGrabbed
||
3470 ( ( nStyle_
& SAL_FRAME_STYLE_PLUG
) && pEvent
->window
== GetShellWindow() )
3473 if( hPresentationWindow
!= None
&& hPresentationWindow
!= GetShellWindow() )
3476 if( FocusIn
== pEvent
->type
)
3478 #ifndef _USE_PRINT_EXTENSION_
3479 vcl_sal::PrinterUpdate::update();
3481 mbInputFocus
= True
;
3482 ImplSVData
* pSVData
= ImplGetSVData();
3486 long nRet
= CallCallback( SALEVENT_GETFOCUS
, 0 );
3487 if ((mpParent
!= NULL
&& nStyle_
== 0)
3488 && pSVData
->maWinData
.mpFirstFloat
)
3490 ULONG nMode
= pSVData
->maWinData
.mpFirstFloat
->GetPopupModeFlags();
3491 pSVData
->maWinData
.mpFirstFloat
->SetPopupModeFlags(
3492 nMode
& ~(FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE
));
3498 mbInputFocus
= False
;
3499 mbSendExtKeyModChange
= mbKeyMenu
= false;
3501 return CallCallback( SALEVENT_LOSEFOCUS
, 0 );
3508 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3510 long X11SalFrame::HandleExposeEvent( XEvent
*pEvent
)
3512 XRectangle aRect
= { 0, 0, 0, 0 };
3515 if( pEvent
->type
== Expose
)
3517 aRect
.x
= pEvent
->xexpose
.x
;
3518 aRect
.y
= pEvent
->xexpose
.y
;
3519 aRect
.width
= pEvent
->xexpose
.width
;
3520 aRect
.height
= pEvent
->xexpose
.height
;
3521 nCount
= pEvent
->xexpose
.count
;
3523 else if( pEvent
->type
== GraphicsExpose
)
3525 aRect
.x
= pEvent
->xgraphicsexpose
.x
;
3526 aRect
.y
= pEvent
->xgraphicsexpose
.y
;
3527 aRect
.width
= pEvent
->xgraphicsexpose
.width
;
3528 aRect
.height
= pEvent
->xgraphicsexpose
.height
;
3529 nCount
= pEvent
->xgraphicsexpose
.count
;
3532 if( IsOverrideRedirect() && mbFullScreen
&&
3533 aPresentationReparentList
.begin() == aPresentationReparentList
.end() )
3534 // we are in fullscreen mode -> override redirect
3535 // focus is possibly lost, so reget it
3536 XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToNone
, CurrentTime
);
3538 // width and height are extents, so they are of by one for rectangle
3539 maPaintRegion
.Union( Rectangle( Point(aRect
.x
, aRect
.y
), Size(aRect
.width
+1, aRect
.height
+1) ) );
3542 // wait for last expose rectangle, do not wait for resize timer
3543 // if a completed graphics expose sequence is available
3546 SalPaintEvent
aPEvt( maPaintRegion
.Left(), maPaintRegion
.Top(), maPaintRegion
.GetWidth(), maPaintRegion
.GetHeight() );
3548 CallCallback( SALEVENT_PAINT
, &aPEvt
);
3549 maPaintRegion
= Rectangle();
3554 void X11SalFrame::RestackChildren( XLIB_Window
* pTopLevelWindows
, int nTopLevelWindows
)
3556 if( maChildren
.begin() != maChildren
.end() )
3558 int nWindow
= nTopLevelWindows
;
3560 if( pTopLevelWindows
[nWindow
] == GetStackingWindow() )
3565 std::list
< X11SalFrame
* >::const_iterator it
;
3566 for( it
= maChildren
.begin(); it
!= maChildren
.end(); ++it
)
3568 X11SalFrame
* pData
= *it
;
3569 if( pData
->bMapped_
)
3571 int nChild
= nWindow
;
3574 if( pTopLevelWindows
[nChild
] == pData
->GetStackingWindow() )
3576 // if a child is behind its parent, place it above the
3577 // parent (for insane WMs like Dtwm and olwm)
3578 XWindowChanges aCfg
;
3579 aCfg
.sibling
= GetStackingWindow();
3580 aCfg
.stack_mode
= Above
;
3581 XConfigureWindow( GetXDisplay(), pData
->GetStackingWindow(), CWSibling
|CWStackMode
, &aCfg
);
3587 for( it
= maChildren
.begin(); it
!= maChildren
.end(); ++it
)
3589 X11SalFrame
* pData
= *it
;
3590 pData
->RestackChildren( pTopLevelWindows
, nTopLevelWindows
);
3595 void X11SalFrame::RestackChildren()
3597 if( ! GetDisplay()->getWMAdaptor()->isTransientBehaviourAsExpected()
3598 && maChildren
.begin() != maChildren
.end() )
3600 XLIB_Window aRoot
, aParent
, *pChildren
= NULL
;
3601 unsigned int nChildren
;
3602 if( XQueryTree( GetXDisplay(),
3603 GetDisplay()->GetRootWindow( m_nScreen
),
3609 RestackChildren( pChildren
, nChildren
);
3615 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3616 long X11SalFrame::HandleSizeEvent( XConfigureEvent
*pEvent
)
3618 if ( pEvent
->window
!= GetShellWindow()
3619 && pEvent
->window
!= GetWindow()
3620 && pEvent
->window
!= GetForeignParent()
3621 && pEvent
->window
!= GetStackingWindow()
3624 // could be as well a sys-child window (aka SalObject)
3629 if( ( nStyle_
& SAL_FRAME_STYLE_PLUG
) && pEvent
->window
== GetShellWindow() )
3631 // just update the children's positions
3636 if( pEvent
->window
== GetForeignParent() )
3637 XResizeWindow( GetXDisplay(),
3643 XTranslateCoordinates( GetXDisplay(),
3645 pDisplay_
->GetRootWindow( pDisplay_
->GetDefaultScreenNumber() ),
3647 &pEvent
->x
, &pEvent
->y
,
3650 if( pEvent
->window
== GetStackingWindow() )
3652 if( maGeometry
.nX
!= pEvent
->x
|| maGeometry
.nY
!= pEvent
->y
)
3654 maGeometry
.nX
= pEvent
->x
;
3655 maGeometry
.nY
= pEvent
->y
;
3656 CallCallback( SALEVENT_MOVE
, NULL
);
3661 // check size hints in first time SalFrame::Show
3662 if( SHOWSTATE_UNKNOWN
== nShowState_
&& bMapped_
)
3663 nShowState_
= SHOWSTATE_NORMAL
;
3665 nWidth_
= pEvent
->width
;
3666 nHeight_
= pEvent
->height
;
3668 bool bMoved
= ( pEvent
->x
!= maGeometry
.nX
|| pEvent
->y
!= maGeometry
.nY
);
3669 bool bSized
= ( pEvent
->width
!= (int)maGeometry
.nWidth
|| pEvent
->height
!= (int)maGeometry
.nHeight
);
3671 maGeometry
.nX
= pEvent
->x
;
3672 maGeometry
.nY
= pEvent
->y
;
3673 maGeometry
.nWidth
= pEvent
->width
;
3674 maGeometry
.nHeight
= pEvent
->height
;
3675 updateScreenNumber();
3677 // update children's position
3680 if( bSized
&& ! bMoved
)
3681 CallCallback( SALEVENT_RESIZE
, NULL
);
3682 else if( bMoved
&& ! bSized
)
3683 CallCallback( SALEVENT_MOVE
, NULL
);
3684 else if( bMoved
&& bSized
)
3685 CallCallback( SALEVENT_MOVERESIZE
, NULL
);
3690 IMPL_LINK( X11SalFrame
, HandleAlwaysOnTopRaise
, void*, EMPTYARG
)
3697 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3698 long X11SalFrame::HandleReparentEvent( XReparentEvent
*pEvent
)
3700 Display
*pDisplay
= pEvent
->display
;
3701 XLIB_Window hWM_Parent
;
3702 XLIB_Window hRoot
, *Children
, hDummy
;
3703 unsigned int nChildren
;
3704 BOOL bNone
= pDisplay_
->GetProperties()
3705 & PROPERTY_SUPPORT_WM_Parent_Pixmap_None
;
3706 BOOL bAccessParentWindow
= ! (pDisplay_
->GetProperties()
3707 & PROPERTY_FEATURE_TrustedSolaris
);
3709 static const char* pDisableStackingCheck
= getenv( "SAL_DISABLE_STACKING_CHECK" );
3711 GetDisplay()->GetXLib()->PushXErrorLevel( true );
3714 * #89186# don't rely on the new parent from the event.
3715 * the event may be "out of date", that is the window manager
3716 * window may not exist anymore. This can happen if someone
3717 * shows a frame and hides it again quickly (not that that would
3720 hWM_Parent
= GetShellWindow();
3724 XQueryTree( pDisplay
,
3730 if( GetDisplay()->GetXLib()->HasXErrorOccured() )
3732 hWM_Parent
= GetShellWindow();
3735 /* #107048# this sometimes happens if a Show(TRUE) is
3736 * immediately followed by Show(FALSE) (which is braindead anyway)
3738 if( hDummy
== hWM_Parent
)
3740 if( hDummy
!= hRoot
)
3742 hWM_Parent
= hDummy
;
3743 if( bAccessParentWindow
&& bNone
)
3744 XSetWindowBackgroundPixmap( pDisplay
, hWM_Parent
, None
);
3748 } while( hDummy
!= hRoot
);
3750 if( GetStackingWindow() == None
3751 && hWM_Parent
!= hPresentationWindow
3752 && hWM_Parent
!= GetShellWindow()
3753 && ( ! pDisableStackingCheck
|| ! *pDisableStackingCheck
)
3756 mhStackingWindow
= hWM_Parent
;
3757 if (bAccessParentWindow
)
3758 XSelectInput( pDisplay
, GetStackingWindow(), StructureNotifyMask
);
3761 if( hWM_Parent
== pDisplay_
->GetRootWindow( pDisplay_
->GetDefaultScreenNumber() )
3762 || hWM_Parent
== GetForeignParent()
3763 || pEvent
->parent
== pDisplay_
->GetRootWindow( pDisplay_
->GetDefaultScreenNumber() )
3764 || ( nStyle_
& SAL_FRAME_STYLE_FLOAT
) )
3766 // Reparenting before Destroy
3767 aPresentationReparentList
.remove( GetStackingWindow() );
3768 mhStackingWindow
= None
;
3769 GetDisplay()->GetXLib()->PopXErrorLevel();
3774 * evil hack to show decorated windows on top
3775 * of override redirect presentation windows:
3776 * reparent the window manager window to the presentation window
3777 * does not work with non-reparenting WMs
3778 * in future this should not be necessary anymore with
3779 * _NET_WM_STATE_FULLSCREEN available
3781 if( hPresentationWindow
!= None
3782 && hPresentationWindow
!= GetWindow()
3783 && GetStackingWindow() != None
3784 && GetStackingWindow() != GetDisplay()->GetRootWindow( m_nScreen
)
3789 XTranslateCoordinates( GetXDisplay(),
3790 GetStackingWindow(),
3791 GetDisplay()->GetRootWindow( m_nScreen
),
3796 XReparentWindow( GetXDisplay(),
3797 GetStackingWindow(),
3798 hPresentationWindow
,
3801 aPresentationReparentList
.push_back( GetStackingWindow() );
3804 int nLeft
= 0, nTop
= 0;
3805 XTranslateCoordinates( GetXDisplay(),
3812 maGeometry
.nLeftDecoration
= nLeft
> 0 ? nLeft
-1 : 0;
3813 maGeometry
.nTopDecoration
= nTop
> 0 ? nTop
-1 : 0;
3816 * decorations are not symmetric,
3817 * so need real geometries here
3818 * (this will fail with virtual roots ?)
3820 GetDisplay()->GetXLib()->ResetXErrorOccured();
3822 unsigned int wp
, w
, hp
, h
, bw
, d
;
3823 XGetGeometry( GetXDisplay(),
3826 &x
, &y
, &w
, &h
, &bw
, &d
);
3827 XGetGeometry( GetXDisplay(),
3830 &xp
, &yp
, &wp
, &hp
, &bw
, &d
);
3831 bool bResized
= false;
3832 if( ! GetDisplay()->GetXLib()->HasXErrorOccured() )
3834 maGeometry
.nRightDecoration
= wp
- w
- maGeometry
.nLeftDecoration
;
3835 maGeometry
.nBottomDecoration
= hp
- h
- maGeometry
.nTopDecoration
;
3837 * note: this works because hWM_Parent is direct child of root,
3838 * not necessarily parent of GetShellWindow()
3840 maGeometry
.nX
= xp
+ nLeft
;
3841 maGeometry
.nY
= yp
+ nTop
;
3842 bResized
= w
!= maGeometry
.nWidth
|| h
!= maGeometry
.nHeight
;
3843 maGeometry
.nWidth
= w
;
3844 maGeometry
.nHeight
= h
;
3848 // limit width and height if we are too large: #47757
3849 // olwm and fvwm need this, it doesnt harm the rest
3851 // #i81311# do this only for sizable frames
3852 if( (nStyle_
& SAL_FRAME_STYLE_SIZEABLE
) != 0 )
3854 Size aScreenSize
= GetDisplay()->GetScreenSize( m_nScreen
);
3855 int nScreenWidth
= aScreenSize
.Width();
3856 int nScreenHeight
= aScreenSize
.Height();
3857 int nFrameWidth
= maGeometry
.nWidth
+ maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
3858 int nFrameHeight
= maGeometry
.nHeight
+ maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
3860 if ((nFrameWidth
> nScreenWidth
) || (nFrameHeight
> nScreenHeight
))
3862 Size
aSize(maGeometry
.nWidth
, maGeometry
.nHeight
);
3864 if (nFrameWidth
> nScreenWidth
)
3865 aSize
.Width() = nScreenWidth
- maGeometry
.nRightDecoration
- maGeometry
.nLeftDecoration
;
3866 if (nFrameHeight
> nScreenHeight
)
3867 aSize
.Height() = nScreenHeight
- maGeometry
.nBottomDecoration
- maGeometry
.nTopDecoration
;
3874 CallCallback( SALEVENT_RESIZE
, NULL
);
3876 GetDisplay()->GetXLib()->PopXErrorLevel();
3881 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3882 long X11SalFrame::HandleColormapEvent( XColormapEvent
* )
3887 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3888 long X11SalFrame::HandleStateEvent( XPropertyEvent
*pEvent
)
3892 unsigned long nitems
, bytes_after
;
3893 unsigned char *prop
= NULL
;
3895 if( 0 != XGetWindowProperty( GetXDisplay(),
3897 pEvent
->atom
, // property
3898 0, // long_offset (32bit)
3899 2, // long_length (32bit)
3901 pEvent
->atom
, // req_type
3911 DBG_ASSERT( actual_type
= pEvent
->atom
3912 && 32 == actual_format
3914 && 0 == bytes_after
, "HandleStateEvent" );
3916 if( *(unsigned long*)prop
== NormalState
)
3917 nShowState_
= SHOWSTATE_NORMAL
;
3918 else if( *(unsigned long*)prop
== IconicState
)
3919 nShowState_
= SHOWSTATE_MINIMIZED
;
3925 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3926 long X11SalFrame::HandleClientMessage( XClientMessageEvent
*pEvent
)
3928 const WMAdaptor
& rWMAdaptor( *pDisplay_
->getWMAdaptor() );
3930 #if !defined(__synchronous_extinput__)
3931 if( pEvent
->message_type
== rWMAdaptor
.getAtom( WMAdaptor::SAL_EXTTEXTEVENT
) )
3933 HandleExtTextEvent (pEvent
);
3937 else if( pEvent
->message_type
== rWMAdaptor
.getAtom( WMAdaptor::SAL_QUITEVENT
) )
3939 stderr0( "X11SalFrame::Dispatch Quit\n" );
3943 else if( pEvent
->message_type
== rWMAdaptor
.getAtom( WMAdaptor::WM_PROTOCOLS
)
3944 && ! ( nStyle_
& SAL_FRAME_STYLE_PLUG
)
3945 && ! (( nStyle_
& SAL_FRAME_STYLE_FLOAT
) && (nStyle_
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
))
3948 if( (Atom
)pEvent
->data
.l
[0] == rWMAdaptor
.getAtom( WMAdaptor::WM_DELETE_WINDOW
) )
3953 else if( (Atom
)pEvent
->data
.l
[0] == rWMAdaptor
.getAtom( WMAdaptor::WM_TAKE_FOCUS
) )
3955 // do nothing, we set the input focus in ToTop() if necessary
3956 #if OSL_DEBUG_LEVEL > 1
3957 fprintf( stderr
, "got WM_TAKE_FOCUS on %s window\n",
3958 (nStyle_
&SAL_FRAME_STYLE_OWNERDRAWDECORATION
) ?
3959 "ownerdraw" : "NON OWNERDRAW" );
3962 else if( (Atom
)pEvent
->data
.l
[0] == rWMAdaptor
.getAtom( WMAdaptor::WM_SAVE_YOURSELF
) )
3964 bool bSession
= rWMAdaptor
.getWindowManagerName().EqualsAscii( "Dtwm" );
3968 if( this == s_pSaveYourselfFrame
)
3970 ByteString
aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() );
3971 const char* argv
[2];
3972 argv
[0] = "/bin/sh";
3973 argv
[1] = const_cast<char*>(aExec
.GetBuffer());
3974 #if OSL_DEBUG_LEVEL > 1
3975 fprintf( stderr
, "SaveYourself request, setting command: %s %s\n", argv
[0], argv
[1] );
3977 XSetCommand( GetXDisplay(), GetShellWindow(), (char**)argv
, 2 );
3980 // can only happen in race between WM and window closing
3981 XChangeProperty( GetXDisplay(), GetShellWindow(), rWMAdaptor
.getAtom( WMAdaptor::WM_COMMAND
), XA_STRING
, 8, PropModeReplace
, (unsigned char*)"", 0 );
3985 // save open documents; would be good for non Dtwm, too,
3986 // but there is no real Shutdown message in the ancient
3987 // SM protocol; on Dtwm SaveYourself really means Shutdown, too.
3988 IceSalSession::handleOldX11SaveYourself( this );
3992 else if( pEvent
->message_type
== rWMAdaptor
.getAtom( WMAdaptor::XEMBED
) &&
3993 pEvent
->window
== GetWindow() )
3995 if( pEvent
->data
.l
[1] == 1 || // XEMBED_WINDOW_ACTIVATE
3996 pEvent
->data
.l
[1] == 2 ) // XEMBED_WINDOW_DEACTIVATE
3998 XFocusChangeEvent aEvent
;
3999 aEvent
.type
= (pEvent
->data
.l
[1] == 1 ? FocusIn
: FocusOut
);
4000 aEvent
.serial
= pEvent
->serial
;
4001 aEvent
.send_event
= True
;
4002 aEvent
.display
= pEvent
->display
;
4003 aEvent
.window
= pEvent
->window
;
4004 aEvent
.mode
= NotifyNormal
;
4005 aEvent
.detail
= NotifyDetailNone
;
4006 HandleFocusEvent( &aEvent
);
4012 void X11SalFrame::SaveYourselfDone( SalFrame
* pSaveFrame
)
4014 // session save was done, inform dtwm
4015 if( s_pSaveYourselfFrame
&& pSaveFrame
)
4017 ByteString
aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() );
4018 const char* argv
[2];
4019 argv
[0] = "/bin/sh";
4020 argv
[1] = const_cast<char*>(aExec
.GetBuffer());
4021 #if OSL_DEBUG_LEVEL > 1
4022 fprintf( stderr
, "SaveYourself request, setting command: %s %s\n", argv
[0], argv
[1] );
4024 XSetCommand( s_pSaveYourselfFrame
->GetXDisplay(),
4025 s_pSaveYourselfFrame
->GetShellWindow(),
4027 if( pSaveFrame
!= s_pSaveYourselfFrame
)
4029 // check if it still exists
4030 const X11SalFrame
* pFrame
= NULL
;
4031 const std::list
< SalFrame
* >& rFrames
= static_cast<X11SalFrame
*>(pSaveFrame
)->GetDisplay()->getFrames();
4032 std::list
< SalFrame
* >::const_iterator it
= rFrames
.begin();
4033 while( it
!= rFrames
.end() )
4035 pFrame
= static_cast< const X11SalFrame
* >(*it
);
4036 if( pFrame
== pSaveFrame
)
4040 if( pFrame
== pSaveFrame
)
4042 const WMAdaptor
& rWMAdaptor( *pFrame
->pDisplay_
->getWMAdaptor() );
4043 XChangeProperty( pFrame
->GetXDisplay(),
4044 pFrame
->GetShellWindow(),
4045 rWMAdaptor
.getAtom( WMAdaptor::WM_COMMAND
), XA_STRING
, 8, PropModeReplace
, (unsigned char*)"", 0 );
4048 s_pSaveYourselfFrame
->ShutDown();
4052 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
4056 Bool
call_checkKeyReleaseForRepeat( Display
* pDisplay
, XEvent
* pCheck
, XPointer pX11SalFrame
)
4058 return X11SalFrame::checkKeyReleaseForRepeat( pDisplay
, pCheck
, pX11SalFrame
);
4062 Bool
X11SalFrame::checkKeyReleaseForRepeat( Display
*, XEvent
* pCheck
, XPointer pX11SalFrame
)
4064 X11SalFrame
* pThis
= (X11SalFrame
*)pX11SalFrame
;
4066 pCheck
->type
== XLIB_KeyPress
&&
4067 pCheck
->xkey
.state
== pThis
->nKeyState_
&&
4068 pCheck
->xkey
.keycode
== pThis
->nKeyCode_
&&
4069 pCheck
->xkey
.time
== pThis
->nReleaseTime_
? True
: False
;
4072 long X11SalFrame::Dispatch( XEvent
*pEvent
)
4076 if( -1 == nCaptured_
)
4078 CaptureMouse( TRUE
);
4080 if( -1 != nCaptured_
)
4081 pDisplay_
->PrintEvent( "Captured", pEvent
);
4085 if( pEvent
->xany
.window
== GetShellWindow() || pEvent
->xany
.window
== GetWindow() )
4087 switch( pEvent
->type
)
4090 nKeyCode_
= pEvent
->xkey
.keycode
;
4091 nKeyState_
= pEvent
->xkey
.state
;
4092 nRet
= HandleKeyEvent( &pEvent
->xkey
);
4096 if( -1 == nCompose_
)
4098 nReleaseTime_
= pEvent
->xkey
.time
;
4100 if( XCheckIfEvent( pEvent
->xkey
.display
, &aEvent
, call_checkKeyReleaseForRepeat
, (XPointer
)this ) )
4101 XPutBackEvent( pEvent
->xkey
.display
, &aEvent
);
4103 nRet
= HandleKeyEvent( &pEvent
->xkey
);
4108 // #74406# if we loose the focus in presentation mode
4109 // there are good chances that we never get it back
4110 // since the WM ignores us
4111 if( IsOverrideRedirect() )
4113 XSetInputFocus( GetXDisplay(), GetShellWindow(),
4114 RevertToNone
, CurrentTime
);
4121 nRet
= HandleMouseEvent( pEvent
);
4126 nRet
= HandleFocusEvent( &pEvent
->xfocus
);
4130 case GraphicsExpose
:
4131 nRet
= HandleExposeEvent( pEvent
);
4135 if( pEvent
->xmap
.window
== GetShellWindow() )
4137 if( nShowState_
== SHOWSTATE_HIDDEN
)
4140 * #95097# workaround for (at least) KWin 2.2.2
4141 * which will map windows that were once transient
4142 * even if they are withdrawn when the respective
4143 * document is mapped.
4145 if( ! (nStyle_
& SAL_FRAME_STYLE_PLUG
) )
4146 XUnmapWindow( GetXDisplay(), GetShellWindow() );
4152 if ( mpInputContext
!= NULL
)
4153 mpInputContext
->Map( this );
4154 CallCallback( SALEVENT_RESIZE
, NULL
);
4155 if( pDisplay_
->GetServerVendor() == vendor_hummingbird
)
4158 * With Exceed sometimes there does not seem to be
4159 * an Expose after the MapNotify.
4160 * so start a delayed paint here
4162 maPaintRegion
.Union( Rectangle( Point( 0, 0 ), Size( maGeometry
.nWidth
, maGeometry
.nHeight
) ) );
4164 aEvent
.xexpose
.type
= Expose
;
4165 aEvent
.xexpose
.display
= pDisplay_
->GetDisplay();
4166 aEvent
.xexpose
.x
= 0;
4167 aEvent
.xexpose
.y
= 0;
4168 aEvent
.xexpose
.width
= maGeometry
.nWidth
;
4169 aEvent
.xexpose
.height
= maGeometry
.nHeight
;
4170 aEvent
.xexpose
.count
= 0;
4171 XSendEvent( pDisplay_
->GetDisplay(),
4178 /* #99570# another workaround for sawfish: if a transient window for the same parent is shown
4179 * sawfish does not set the focus to it. Applies only for click to focus mode.
4181 if( ! (nStyle_
& SAL_FRAME_STYLE_FLOAT
) && mbInShow
&& GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii( "Sawfish" ) )
4183 // #101775# don't set the focus into the IME status window
4184 // since this will lead to a parent loose-focus, close status,
4185 // reget focus, open status, .... flicker loop
4186 if ( (I18NStatus::get().getStatusFrame() != this) )
4187 XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToParent
, CurrentTime
);
4191 * sometimes a message box/dialogue is brought up when a frame is not mapped
4192 * the corresponding TRANSIENT_FOR hint is then set to the root window
4193 * so that the dialogue shows in all cases. Correct it here if the
4194 * frame is shown afterwards.
4196 if( ! IsChildWindow()
4197 && ! IsOverrideRedirect()
4198 && ! IsFloatGrabWindow()
4201 for( std::list
< X11SalFrame
* >::const_iterator it
= maChildren
.begin();
4202 it
!= maChildren
.end(); ++it
)
4204 if( (*it
)->mbTransientForRoot
)
4205 pDisplay_
->getWMAdaptor()->changeReferenceFrame( *it
, this );
4209 if( hPresentationWindow
!= None
&& GetShellWindow() == hPresentationWindow
)
4210 XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToParent
, CurrentTime
);
4211 /* For unknown reasons Dtwm does respect the input_hint
4212 * set to False, but not when mapping the window. So
4213 * emulate the correct behaviour and set the focus back
4214 * to where it most probably should have been.
4216 if( (nStyle_
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) &&
4218 GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii( "Dtwm" )
4221 XSetInputFocus( GetXDisplay(),
4222 mpParent
->GetShellWindow(),
4233 if( pEvent
->xunmap
.window
== GetShellWindow() )
4238 if ( mpInputContext
!= NULL
)
4239 mpInputContext
->Unmap( this );
4240 CallCallback( SALEVENT_RESIZE
, NULL
);
4244 case ConfigureNotify
:
4245 if( pEvent
->xconfigure
.window
== GetShellWindow()
4246 || pEvent
->xconfigure
.window
== GetWindow() )
4247 nRet
= HandleSizeEvent( &pEvent
->xconfigure
);
4250 case VisibilityNotify
:
4251 nVisibility_
= pEvent
->xvisibility
.state
;
4255 && ! GetDisplay()->getWMAdaptor()->isAlwaysOnTopOK()
4256 && nVisibility_
!= VisibilityUnobscured
)
4257 maAlwaysOnTopRaiseTimer
.Start();
4260 case ReparentNotify
:
4261 nRet
= HandleReparentEvent( &pEvent
->xreparent
);
4265 if( MappingPointer
!= pEvent
->xmapping
.request
)
4266 nRet
= CallCallback( SALEVENT_KEYBOARDCHANGED
, 0 );
4269 case ColormapNotify
:
4270 nRet
= HandleColormapEvent( &pEvent
->xcolormap
);
4273 case PropertyNotify
:
4275 if( pEvent
->xproperty
.atom
== pDisplay_
->getWMAdaptor()->getAtom( WMAdaptor::WM_STATE
) )
4276 nRet
= HandleStateEvent( &pEvent
->xproperty
);
4278 nRet
= pDisplay_
->getWMAdaptor()->handlePropertyNotify( this, &pEvent
->xproperty
);
4283 nRet
= HandleClientMessage( &pEvent
->xclient
);
4289 switch( pEvent
->type
)
4293 if( ( nStyle_
& SAL_FRAME_STYLE_PLUG
)
4294 && ( pEvent
->xfocus
.window
== GetShellWindow()
4295 || pEvent
->xfocus
.window
== GetForeignParent() )
4298 nRet
= HandleFocusEvent( &pEvent
->xfocus
);
4302 case ConfigureNotify
:
4303 if( pEvent
->xconfigure
.window
== GetForeignParent() ||
4304 pEvent
->xconfigure
.window
== GetShellWindow() )
4305 nRet
= HandleSizeEvent( &pEvent
->xconfigure
);
4307 if( pEvent
->xconfigure
.window
== GetStackingWindow() )
4308 nRet
= HandleSizeEvent( &pEvent
->xconfigure
);
4318 void X11SalFrame::ResetClipRegion()
4320 delete [] m_pClipRectangles
;
4321 m_pClipRectangles
= NULL
;
4322 m_nCurClipRect
= m_nMaxClipRect
= 0;
4324 const int dest_kind
= ShapeBounding
;
4325 const int op
= ShapeSet
;
4326 const int ordering
= YSorted
;
4328 XWindowAttributes win_attrib
;
4329 XRectangle win_size
;
4331 XLIB_Window aShapeWindow
= mhShellWindow
;
4333 XGetWindowAttributes ( GetDisplay()->GetDisplay(),
4339 win_size
.width
= win_attrib
.width
;
4340 win_size
.height
= win_attrib
.height
;
4342 XShapeCombineRectangles ( GetDisplay()->GetDisplay(),
4345 0, 0, // x_off, y_off
4346 &win_size
, // list of rectangles
4347 1, // number of rectangles
4351 void X11SalFrame::BeginSetClipRegion( ULONG nRects
)
4353 if( m_pClipRectangles
)
4354 delete [] m_pClipRectangles
;
4356 m_pClipRectangles
= new XRectangle
[nRects
];
4358 m_pClipRectangles
= NULL
;
4359 m_nMaxClipRect
= static_cast<int>(nRects
);
4363 void X11SalFrame::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
4365 if( m_pClipRectangles
&& m_nCurClipRect
< m_nMaxClipRect
)
4367 m_pClipRectangles
[m_nCurClipRect
].x
= nX
;
4368 m_pClipRectangles
[m_nCurClipRect
].y
= nY
;
4369 m_pClipRectangles
[m_nCurClipRect
].width
= nWidth
;
4370 m_pClipRectangles
[m_nCurClipRect
].height
= nHeight
;
4375 void X11SalFrame::EndSetClipRegion()
4377 const int dest_kind
= ShapeBounding
;
4378 const int ordering
= YSorted
;
4379 const int op
= ShapeSet
;
4381 XLIB_Window aShapeWindow
= mhShellWindow
;
4382 XShapeCombineRectangles ( GetDisplay()->GetDisplay(),
4385 0, 0, // x_off, y_off