summaryrefslogtreecommitdiff
path: root/vcl/inc/unx/wmadaptor.hxx
blob: 177ca34780a1168ae23623c2245789bb1287f21c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_VCL_INC_UNX_WMADAPTOR_HXX
#define INCLUDED_VCL_INC_UNX_WMADAPTOR_HXX

#include <rtl/ustring.hxx>
#include <tools/gen.hxx>

#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include <vclpluginapi.h>
#include <vector>

class SalDisplay;
class X11SalFrame;

namespace vcl_sal {

class VCLPLUG_GEN_PUBLIC WMAdaptor
{
public:
    enum WMAtom {
        // atoms for types
        UTF8_STRING,

        // atoms for extended WM hints
        NET_SUPPORTED,
        NET_SUPPORTING_WM_CHECK,
        NET_WM_NAME,
        NET_WM_DESKTOP,
        NET_WM_ICON_NAME,
        NET_WM_PID,
        NET_WM_PING,
        NET_WM_STATE,
        NET_WM_STATE_MAXIMIZED_HORZ,
        NET_WM_STATE_MAXIMIZED_VERT,
        NET_WM_STATE_MODAL,
        NET_WM_STATE_SHADED,
        NET_WM_STATE_SKIP_PAGER,
        NET_WM_STATE_SKIP_TASKBAR,
        NET_WM_STATE_STAYS_ON_TOP,
        NET_WM_STATE_STICKY,
        NET_WM_STATE_FULLSCREEN,
        NET_WM_STRUT,
        NET_WM_STRUT_PARTIAL,
        NET_WM_USER_TIME,
        NET_WM_WINDOW_TYPE,
        NET_WM_WINDOW_TYPE_DESKTOP,
        NET_WM_WINDOW_TYPE_DIALOG,
        NET_WM_WINDOW_TYPE_DOCK,
        NET_WM_WINDOW_TYPE_MENU,
        NET_WM_WINDOW_TYPE_NORMAL,
        NET_WM_WINDOW_TYPE_TOOLBAR,
        KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
        NET_WM_WINDOW_TYPE_SPLASH,
        NET_WM_WINDOW_TYPE_UTILITY,
        NET_NUMBER_OF_DESKTOPS,
        NET_CURRENT_DESKTOP,
        NET_WORKAREA,
        NET_WM_ICON,

        // atoms for Gnome WM hints
        WIN_SUPPORTING_WM_CHECK,
        WIN_PROTOCOLS,
        WIN_WORKSPACE_COUNT,
        WIN_WORKSPACE,
        WIN_LAYER,
        WIN_STATE,
        WIN_HINTS,
        WIN_APP_STATE,
        WIN_EXPANDED_SIZE,
        WIN_ICONS,
        WIN_WORKSPACE_NAMES,
        WIN_CLIENT_LIST,

        // atoms for general WM hints
        WM_STATE,
        MOTIF_WM_HINTS,
        WM_PROTOCOLS,
        WM_DELETE_WINDOW,
        WM_TAKE_FOCUS,
        WM_CLIENT_LEADER,
        WM_COMMAND,
        WM_LOCALE_NAME,
        WM_TRANSIENT_FOR,

        // special atoms
        SAL_QUITEVENT,
        SAL_USEREVENT,
        SAL_EXTTEXTEVENT,
        SAL_GETTIMEEVENT,
        DTWM_IS_RUNNING,
        VCL_SYSTEM_SETTINGS,
        XSETTINGS,
        XEMBED,
        XEMBED_INFO,
        NetAtomMax
    };

    /*
     *  flags for frame decoration
     */
    static const int decoration_Title           = 0x00000001;
    static const int decoration_Border      = 0x00000002;
    static const int decoration_Resize      = 0x00000004;
    static const int decoration_MinimizeBtn = 0x00000008;
    static const int decoration_MaximizeBtn = 0x00000010;
    static const int decoration_CloseBtn        = 0x00000020;
    static const int decoration_All         = 0x10000000;

    /*
     *  window type
     */
    enum WMWindowType
    {
        windowType_Normal,
        windowType_ModalDialogue,
        windowType_ModelessDialogue,
        windowType_Utility,
        windowType_Splash,
        windowType_Toolbar,
        windowType_Dock
    };

protected:
    SalDisplay*             m_pSalDisplay;      // Display to use
    Display*                m_pDisplay;         // X Display of SalDisplay
    OUString                m_aWMName;
    Atom                    m_aWMAtoms[ NetAtomMax];
    int                     m_nDesktops;
    bool                    m_bEqualWorkAreas;
    ::std::vector< Rectangle >
                            m_aWMWorkAreas;
    bool                    m_bTransientBehaviour;
    bool                    m_bEnableAlwaysOnTopWorks;
    bool                    m_bLegacyPartialFullscreen;
    int                     m_nWinGravity;
    int                     m_nInitWinGravity;
    bool                    m_bWMshouldSwitchWorkspace;
    bool                    m_bWMshouldSwitchWorkspaceInit;

    WMAdaptor( SalDisplay * )
;
    void initAtoms();
    bool getNetWmName();

    /*
     *  returns whether this instance is useful
     *  only useful for createWMAdaptor
     */
    virtual bool isValid() const;

    bool getWMshouldSwitchWorkspace() const;
public:
    virtual ~WMAdaptor();

    /*
     *  creates a valid WMAdaptor instance for the SalDisplay
     */
    static WMAdaptor* createWMAdaptor( SalDisplay* );

    /*
     *  may return an empty string if the window manager could
     *  not be identified.
     */
    const OUString& getWindowManagerName() const
    { return m_aWMName; }

    /*
     * gets the current work area/desktop number: [0,m_nDesktops[ or -1 if unknown
     */
    int getCurrentWorkArea() const;
    /*
     * gets the workarea the specified window is on (or -1)
     */
    int getWindowWorkArea( ::Window aWindow ) const;
    /*
     *  gets the specified workarea
     */
    const Rectangle& getWorkArea( int n ) const
    { return m_aWMWorkAreas[n]; }

    /*
     * attempt to switch the desktop to a certain workarea (ie. virtual desktops)
     */
    void switchToWorkArea( int nWorkArea ) const;

    /*
     *  sets window title
     */
    virtual void setWMName( X11SalFrame* pFrame, const OUString& rWMName ) const;

    /*
     * set NET_WM_PID
     */
    void setPID( X11SalFrame* pFrame ) const;

    /*
     * set WM_CLIENT_MACHINE
     */
    void setClientMachine( X11SalFrame* pFrame ) const;

    void answerPing( X11SalFrame*, XClientMessageEvent* ) const;

    /*
     *  maximizes frame
     *  maximization can be toggled in either direction
     *  to get the original position and size
     *  use maximizeFrame( pFrame, false, false )
     */
    virtual void maximizeFrame( X11SalFrame* pFrame, bool bHorizontal = true, bool bVertical = true ) const;
    /*
     *  start/stop fullscreen mode on a frame
     */
    virtual void showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const;
    /*
     *  tell whether legacy partial full screen handling is necessary
     *  see #i107249#: NET_WM_STATE_FULLSCREEN is not well defined, but de facto
     *  modern WM's interpret it the "right" way, namely they make "full screen"
     *  taking twin view or Xinerama into account and honor the positioning hints
     *  to see which screen actually was meant to use for fullscreen.
     */
    bool isLegacyPartialFullscreen() const
    { return m_bLegacyPartialFullscreen; }
    /*
     * set _NET_WM_USER_TIME property, if NetWM
     */
    virtual void setUserTime( X11SalFrame* i_pFrame, long i_nUserTime ) const;

    /*
     *  tells whether fullscreen mode is supported by WM
     */
    bool supportsFullScreen() const { return m_aWMAtoms[ NET_WM_STATE_FULLSCREEN ] != 0; }

    /*
     *  shade/unshade frame
     */
    virtual void shade( X11SalFrame* pFrame, bool bToShaded ) const;

    /*
     *  set hints what decoration is needed;
     *  must be called before showing the frame
     */
    virtual void setFrameTypeAndDecoration( X11SalFrame* pFrame, WMWindowType eType, int nDecorationFlags, X11SalFrame* pTransientFrame = nullptr ) const;

    /*
     *  tells whether there is WM support for splash screens
     */
    bool supportsSplash() const { return m_aWMAtoms[ NET_WM_WINDOW_TYPE_SPLASH ] != 0; }

    /*
     *  enables always on top or equivalent if possible
     */
    virtual void enableAlwaysOnTop( X11SalFrame* pFrame, bool bEnable ) const;

    /*
     *  tells whether enableAlwaysOnTop actually works with this WM
     */
    bool isAlwaysOnTopOK() const { return m_bEnableAlwaysOnTopWorks; }

    /*
     *  handle WM messages (especially WM state changes)
     */
    virtual int handlePropertyNotify( X11SalFrame* pFrame, XPropertyEvent* pEvent ) const;

    /*
     * called by SalFrame::Show: time to update state properties
     */
    virtual void frameIsMapping( X11SalFrame* ) const;

    /*
     *  gets a WM atom
     */
    Atom getAtom( WMAtom eAtom ) const
    { return m_aWMAtoms[ eAtom ]; }

    int getPositionWinGravity () const
    { return m_nWinGravity; }
    int getInitWinGravity() const
    { return m_nInitWinGravity; }

    /*
     *  expected behaviour is that the WM will not allow transient
     *  windows to get stacked behind the windows they are transient for
     */
    bool isTransientBehaviourAsExpected() const
    { return m_bTransientBehaviour; }

    /*
     *  changes the transient hint of a window to reference frame
     *  if reference frame is NULL the root window is used instead
     */
    void changeReferenceFrame( X11SalFrame* pFrame, X11SalFrame* pReferenceFrame ) const;
};

} // namespace

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */