~ubuntu-branches/ubuntu/wily/kwin/wily-proposed

« back to all changes in this revision

Viewing changes to client.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-08-10 23:16:37 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20150810231637-5zb2tstjkez93hml
Tags: 4:5.3.95-0ubuntu1
new upstream beta release

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include "focuschain.h"
33
33
#include "group.h"
34
34
#include "shadow.h"
35
 
#ifdef KWIN_BUILD_TABBOX
36
 
#include "tabbox.h"
37
 
#endif
38
35
#include "workspace.h"
39
36
#include "screenedge.h"
40
37
#include "decorations/decorationbridge.h"
48
45
#include <QApplication>
49
46
#include <QDebug>
50
47
#include <QFile>
 
48
#include <QMouseEvent>
51
49
#include <QProcess>
52
50
#include <QStandardPaths>
53
51
#include <QScriptEngine>
79
77
                           XCB_EVENT_MASK_STRUCTURE_NOTIFY |
80
78
                           XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
81
79
 
82
 
QHash<QString, std::weak_ptr<Decoration::DecorationPalette>> Client::s_palettes;
83
 
std::shared_ptr<Decoration::DecorationPalette> Client::s_defaultPalette;
84
 
 
85
80
// Creating a client:
86
81
//  - only by calling Workspace::createClient()
87
82
//      - it creates a new client and calls manage() for it
100
95
 * is done in manage().
101
96
 */
102
97
Client::Client()
103
 
    : Toplevel()
 
98
    : AbstractClient()
104
99
    , m_client()
105
100
    , m_wrapper()
106
101
    , m_frame()
114
109
    , m_transientForId(XCB_WINDOW_NONE)
115
110
    , m_originalTransientForId(XCB_WINDOW_NONE)
116
111
    , shade_below(NULL)
117
 
    , skip_switcher(false)
118
112
    , m_motif(atoms->motif_wm_hints)
119
113
    , blocks_compositing(false)
120
114
    , m_cursor(Qt::ArrowCursor)
121
 
    , autoRaiseTimer(NULL)
122
115
    , shadeHoverTimer(NULL)
123
116
    , delayedMoveResizeTimer(NULL)
124
117
    , m_colormap(XCB_COLORMAP_NONE)
134
127
    , pending_geometry_update(PendingGeometryNone)
135
128
    , shade_geometry_change(false)
136
129
    , sm_stacking_order(-1)
137
 
    , m_firstInTabBox(false)
138
130
    , electricMaximizing(false)
139
131
    , activitiesDefined(false)
140
132
    , needsSessionInteract(false)
141
133
    , needsXWindowMove(false)
142
134
    , m_decoInputExtent()
143
135
    , m_focusOutTimer(nullptr)
144
 
    , m_colorScheme(QStringLiteral("kdeglobals"))
145
136
    , m_clientSideDecorated(false)
146
137
{
147
138
    // TODO: Do all as initialization
153
144
    // Set the initial mapping state
154
145
    mapping_state = Withdrawn;
155
146
    quick_tile_mode = QuickTileNone;
156
 
    desk = 0; // No desktop yet
157
147
 
158
148
    mode = PositionCenter;
159
149
    buttonDown = false;
162
152
    info = NULL;
163
153
 
164
154
    shade_mode = ShadeNone;
165
 
    active = false;
166
155
    deleting = false;
167
 
    keep_above = false;
168
 
    keep_below = false;
169
156
    fullscreen_mode = FullScreenNone;
170
 
    skip_taskbar = false;
171
 
    original_skip_taskbar = false;
172
 
    minimized = false;
173
157
    hidden = false;
174
158
    modal = false;
175
159
    noborder = false;
176
160
    app_noborder = false;
177
161
    ignore_focus_stealing = false;
178
 
    demands_attention = false;
179
162
    check_active_modal = false;
180
163
 
181
 
    skip_pager = false;
182
 
 
183
164
    max_mode = MaximizeRestore;
184
165
 
185
166
    //Client to workspace connections require that each
186
167
    //client constructed be connected to the workspace wrapper
187
168
 
188
 
#ifdef KWIN_BUILD_TABBOX
189
 
    // TabBoxClient
190
 
    m_tabBoxClient = QSharedPointer<TabBox::TabBoxClientImpl>(new TabBox::TabBoxClientImpl(this));
191
 
#endif
192
 
 
193
169
    geom = QRect(0, 0, 100, 100);   // So that decorations don't start with size being (0,0)
194
170
    client_size = QSize(100, 100);
195
171
    ready_for_painting = false; // wait for first damage or sync reply
196
172
 
197
173
    connect(this, &Client::geometryShapeChanged, this, &Client::geometryChanged);
198
 
    auto signalMaximizeChanged = static_cast<void (Client::*)(KWin::Client*, MaximizeMode)>(&Client::clientMaximizedStateChanged);
 
174
    auto signalMaximizeChanged = static_cast<void (Client::*)(KWin::AbstractClient*, MaximizeMode)>(&Client::clientMaximizedStateChanged);
199
175
    connect(this, signalMaximizeChanged, this, &Client::geometryChanged);
200
176
    connect(this, &Client::clientStepUserMovedResized,   this, &Client::geometryChanged);
201
177
    connect(this, &Client::clientStartUserMovedResized,  this, &Client::moveResizedChanged);
202
178
    connect(this, &Client::clientFinishUserMovedResized, this, &Client::moveResizedChanged);
203
179
    connect(this, &Client::clientStartUserMovedResized,  this, &Client::removeCheckScreenConnection);
204
180
    connect(this, &Client::clientFinishUserMovedResized, this, &Client::setupCheckScreenConnection);
 
181
    connect(this, &Client::paletteChanged, this, &Client::triggerDecorationRepaint);
205
182
 
206
183
    connect(clientMachine(), &ClientMachine::localhostChanged, this, &Client::updateCaption);
207
184
    connect(options, &Options::condensedTitleChanged, this, &Client::updateCaption);
246
223
{
247
224
    assert(!deleting);
248
225
    deleting = true;
 
226
    destroyWindowManagementInterface();
249
227
    Deleted* del = NULL;
250
228
    if (!on_shutdown) {
251
229
        del = Deleted::create(this);
277
255
        workspace()->removeClient(this);
278
256
        // Only when the window is being unmapped, not when closing down KWin (NETWM sections 5.5,5.7)
279
257
        info->setDesktop(0);
280
 
        desk = 0;
281
258
        info->setState(0, info->state());  // Reset all state flags
282
259
    } else
283
260
        untab();
317
294
{
318
295
    assert(!deleting);
319
296
    deleting = true;
 
297
    destroyWindowManagementInterface();
320
298
    Deleted* del = Deleted::create(this);
321
299
    if (moveResizeMode)
322
300
        emit clientFinishUserMovedResized(this);
410
388
            ((m_decoration == NULL && noBorder()) || (m_decoration != NULL && !noBorder())))
411
389
        return;
412
390
    QRect oldgeom = geometry();
 
391
    QRect oldClientGeom = oldgeom.adjusted(borderLeft(), borderTop(), -borderRight(), -borderBottom());
413
392
    blockGeometryUpdates(true);
414
393
    if (force)
415
394
        destroyDecoration();
419
398
        destroyDecoration();
420
399
    getShadow();
421
400
    if (check_workspace_pos)
422
 
        checkWorkspacePosition(oldgeom);
 
401
        checkWorkspacePosition(oldgeom, -2, oldClientGeom);
423
402
    updateInputWindow();
424
403
    blockGeometryUpdates(false);
425
404
    updateFrameExtents();
435
414
        connect(m_decoration, &KDecoration2::Decoration::bordersChanged, this,
436
415
            [this]() {
437
416
                GeometryUpdatesBlocker blocker(this);
438
 
                move(calculateGravitation(true));
439
 
                move(calculateGravitation(false));
 
417
                // TODO: this is obviously idempotent
 
418
                // calculateGravitation(true) would have to operate on the old border sizes
 
419
//                 move(calculateGravitation(true));
 
420
//                 move(calculateGravitation(false));
440
421
                QRect oldgeom = geometry();
441
422
                plainResize(sizeForClientSize(clientSize()), ForceGeometrySet);
442
 
                checkWorkspacePosition(oldgeom);
 
423
                if (!isShade())
 
424
                    checkWorkspacePosition(oldgeom);
443
425
                emit geometryShapeChanged(this, oldgeom);
444
426
            }
445
427
        );
746
728
    return true;
747
729
}
748
730
 
749
 
void Client::setMinimized(bool set)
750
 
{
751
 
    set ? minimize() : unminimize();
752
 
}
753
 
 
754
 
/**
755
 
 * Minimizes this client plus its transients
756
 
 */
757
 
void Client::minimize(bool avoid_animation)
758
 
{
759
 
    if (!isMinimizable() || isMinimized())
760
 
        return;
761
 
 
762
 
    if (isShade()) // NETWM restriction - KWindowInfo::isMinimized() == Hidden && !Shaded
763
 
        info->setState(0, NET::Shaded);
764
 
 
765
 
    minimized = true;
766
 
 
767
 
    updateVisibility();
768
 
    updateAllowedActions();
769
 
    workspace()->updateMinimizedOfTransients(this);
770
 
    updateWindowRules(Rules::Minimize);
771
 
    FocusChain::self()->update(this, FocusChain::MakeFirstMinimized);
772
 
    // TODO: merge signal with s_minimized
773
 
    emit clientMinimized(this, !avoid_animation);
774
 
 
775
 
    // Update states of all other windows in this group
776
 
    if (tabGroup())
777
 
        tabGroup()->updateStates(this, TabGroup::Minimized);
778
 
    emit minimizedChanged();
779
 
}
780
 
 
781
 
void Client::unminimize(bool avoid_animation)
782
 
{
783
 
    if (!isMinimized())
784
 
        return;
785
 
 
786
 
    if (rules()->checkMinimize(false)) {
787
 
        return;
788
 
    }
789
 
 
790
 
    if (isShade()) // NETWM restriction - KWindowInfo::isMinimized() == Hidden && !Shaded
791
 
        info->setState(NET::Shaded, NET::Shaded);
792
 
 
793
 
    minimized = false;
794
 
    updateVisibility();
795
 
    updateAllowedActions();
796
 
    workspace()->updateMinimizedOfTransients(this);
797
 
    updateWindowRules(Rules::Minimize);
798
 
    emit clientUnminimized(this, !avoid_animation);
799
 
 
800
 
    // Update states of all other windows in this group
801
 
    if (tabGroup())
802
 
        tabGroup()->updateStates(this, TabGroup::Minimized);
803
 
    emit minimizedChanged();
 
731
void Client::doMinimize()
 
732
{
 
733
    updateVisibility();
 
734
    updateAllowedActions();
 
735
    workspace()->updateMinimizedOfTransients(this);
 
736
    // Update states of all other windows in this group
 
737
    if (tabGroup())
 
738
        tabGroup()->updateStates(this, TabGroup::Minimized);
804
739
}
805
740
 
806
741
QRect Client::iconGeometry() const
826
761
    return !isSpecialWindow() && !noBorder() && (rules()->checkShade(ShadeNormal) != rules()->checkShade(ShadeNone));
827
762
}
828
763
 
829
 
void Client::setShade(bool set) {
830
 
    set ? setShade(ShadeNormal) : setShade(ShadeNone);
831
 
}
832
 
 
833
764
void Client::setShade(ShadeMode mode)
834
765
{
835
766
    if (mode == ShadeHover && isMove())
891
822
        QSize s(sizeForClientSize(clientSize()));
892
823
        shade_geometry_change = false;
893
824
        plainResize(s);
 
825
        geom_restore = geometry();
894
826
        if ((shade_mode == ShadeHover || shade_mode == ShadeActivated) && rules()->checkAcceptFocus(info->input()))
895
827
            setActive(true);
896
828
        if (shade_mode == ShadeHover) {
957
889
        return;
958
890
    if (hidden && isCurrentTab()) {
959
891
        info->setState(NET::Hidden, NET::Hidden);
960
 
        setSkipTaskbar(true, false);   // Also hide from taskbar
 
892
        setSkipTaskbar(true);   // Also hide from taskbar
961
893
        if (compositing() && options->hiddenPreviews() == HiddenPreviewsAlways)
962
894
            internalKeep();
963
895
        else
965
897
        return;
966
898
    }
967
899
    if (isCurrentTab())
968
 
        setSkipTaskbar(original_skip_taskbar, false);   // Reset from 'hidden'
969
 
    if (minimized) {
 
900
        setSkipTaskbar(originalSkipTaskbar());   // Reset from 'hidden'
 
901
    if (isMinimized()) {
970
902
        info->setState(NET::Hidden, NET::Hidden);
971
903
        if (compositing() && options->hiddenPreviews() == HiddenPreviewsAlways)
972
904
            internalKeep();
1263
1195
    }
1264
1196
}
1265
1197
 
1266
 
void Client::setSkipTaskbar(bool b, bool from_outside)
1267
 
{
1268
 
    int was_wants_tab_focus = wantsTabFocus();
1269
 
    if (from_outside) {
1270
 
        b = rules()->checkSkipTaskbar(b);
1271
 
        original_skip_taskbar = b;
1272
 
    }
1273
 
    if (b == skipTaskbar())
1274
 
        return;
1275
 
    skip_taskbar = b;
1276
 
    info->setState(b ? NET::SkipTaskbar : NET::States(0), NET::SkipTaskbar);
1277
 
    updateWindowRules(Rules::SkipTaskbar);
1278
 
    if (was_wants_tab_focus != wantsTabFocus())
1279
 
        FocusChain::self()->update(this,
1280
 
                                          isActive() ? FocusChain::MakeFirst : FocusChain::Update);
1281
 
    emit skipTaskbarChanged();
1282
 
}
1283
 
 
1284
 
void Client::setSkipPager(bool b)
1285
 
{
1286
 
    b = rules()->checkSkipPager(b);
1287
 
    if (b == skipPager())
1288
 
        return;
1289
 
    skip_pager = b;
1290
 
    info->setState(b ? NET::SkipPager : NET::States(0), NET::SkipPager);
1291
 
    updateWindowRules(Rules::SkipPager);
1292
 
    emit skipPagerChanged();
1293
 
}
1294
 
 
1295
 
void Client::setSkipSwitcher(bool set)
1296
 
{
1297
 
    set = rules()->checkSkipSwitcher(set);
1298
 
    if (set == skipSwitcher())
1299
 
        return;
1300
 
    skip_switcher = set;
1301
 
    updateWindowRules(Rules::SkipSwitcher);
1302
 
    emit skipSwitcherChanged();
 
1198
void Client::doSetSkipTaskbar()
 
1199
{
 
1200
    info->setState(skipTaskbar() ? NET::SkipTaskbar : NET::States(0), NET::SkipTaskbar);
 
1201
}
 
1202
 
 
1203
void Client::doSetSkipPager()
 
1204
{
 
1205
    info->setState(skipPager() ? NET::SkipPager : NET::States(0), NET::SkipPager);
1303
1206
}
1304
1207
 
1305
1208
void Client::setModal(bool m)
1313
1216
    // _NET_WM_STATE_MODAL should possibly rather be _NET_WM_WINDOW_TYPE_MODAL_DIALOG
1314
1217
}
1315
1218
 
1316
 
void Client::setDesktop(int desktop)
 
1219
void Client::doSetDesktop(int desktop, int was_desk)
1317
1220
{
1318
 
    const int numberOfDesktops = VirtualDesktopManager::self()->count();
1319
 
    if (desktop != NET::OnAllDesktops)   // Do range check
1320
 
        desktop = qMax(1, qMin(numberOfDesktops, desktop));
1321
 
    desktop = qMin(numberOfDesktops, rules()->checkDesktop(desktop));
1322
 
    if (desk == desktop)
1323
 
        return;
1324
 
 
1325
 
    int was_desk = desk;
1326
 
    const bool wasOnCurrentDesktop = isOnCurrentDesktop();
1327
 
    desk = desktop;
1328
1221
    info->setDesktop(desktop);
1329
1222
    if ((was_desk == NET::OnAllDesktops) != (desktop == NET::OnAllDesktops)) {
1330
1223
        // onAllDesktops changed
1344
1237
        foreach (Client * c2, mainClients())
1345
1238
        c2->setDesktop(desktop);
1346
1239
    }
1347
 
 
1348
 
    FocusChain::self()->update(this, FocusChain::MakeFirst);
1349
1240
    updateVisibility();
1350
 
    updateWindowRules(Rules::Desktop);
1351
1241
 
1352
1242
    // Update states of all other windows in this group
1353
1243
    if (tabGroup())
1354
1244
        tabGroup()->updateStates(this, TabGroup::Desktop);
1355
 
    emit desktopChanged();
1356
 
    if (wasOnCurrentDesktop != isOnCurrentDesktop())
1357
 
        emit desktopPresenceChanged(this, was_desk);
1358
1245
}
1359
1246
 
1360
1247
/**
1367
1254
void Client::setOnActivity(const QString &activity, bool enable)
1368
1255
{
1369
1256
#ifdef KWIN_BUILD_ACTIVITIES
 
1257
    if (! Activities::self()) {
 
1258
        return;
 
1259
    }
1370
1260
    QStringList newActivitiesList = activities();
1371
1261
    if (newActivitiesList.contains(activity) == enable)   //nothing to do
1372
1262
        return;
1390
1280
void Client::setOnActivities(QStringList newActivitiesList)
1391
1281
{
1392
1282
#ifdef KWIN_BUILD_ACTIVITIES
 
1283
    if (!Activities::self()) {
 
1284
        return;
 
1285
    }
1393
1286
    QString joinedActivitiesList = newActivitiesList.join(QStringLiteral(","));
1394
1287
    joinedActivitiesList = rules()->checkActivity(joinedActivitiesList, false);
1395
1288
    newActivitiesList = joinedActivitiesList.split(QStringLiteral(","), QString::SkipEmptyParts);
1459
1352
    if (needsSessionInteract) {
1460
1353
        return NET::OnAllDesktops;
1461
1354
    }
1462
 
    return desk;
 
1355
    return AbstractClient::desktop();
1463
1356
}
1464
1357
 
1465
1358
/**
1475
1368
    return activityList;
1476
1369
}
1477
1370
 
1478
 
void Client::setOnAllDesktops(bool b)
1479
 
{
1480
 
    if ((b && isOnAllDesktops()) ||
1481
 
            (!b && !isOnAllDesktops()))
1482
 
        return;
1483
 
    if (b)
1484
 
        setDesktop(NET::OnAllDesktops);
1485
 
    else
1486
 
        setDesktop(VirtualDesktopManager::self()->current());
1487
 
 
1488
 
    // Update states of all other windows in this group
1489
 
    if (tabGroup())
1490
 
        tabGroup()->updateStates(this, TabGroup::Desktop);
1491
 
}
1492
 
 
1493
1371
/**
1494
1372
 * if @p on is true, sets on all activities.
1495
1373
 * if it's false, sets it to only be on the current activity
1812
1690
        return; // nothing to change
1813
1691
    hidden = !shown;
1814
1692
    if (options->isInactiveTabsSkipTaskbar())
1815
 
        setSkipTaskbar(hidden, false); // TODO: Causes reshuffle of the taskbar
 
1693
        setSkipTaskbar(hidden); // TODO: Causes reshuffle of the taskbar
1816
1694
    if (shown) {
1817
1695
        map();
1818
1696
        takeFocus();
1855
1733
void Client::getIcons()
1856
1734
{
1857
1735
    // First read icons from the window itself
1858
 
    m_icon = QIcon();
1859
 
    auto readIcon = [this](int size, bool scale = true) {
 
1736
    QIcon icon;
 
1737
    auto readIcon = [this, &icon](int size, bool scale = true) {
1860
1738
        const QPixmap pix = KWindowSystem::icon(window(), size, size, scale, KWindowSystem::NETWM | KWindowSystem::WMHints, info);
1861
1739
        if (!pix.isNull()) {
1862
 
            m_icon.addPixmap(pix);
 
1740
            icon.addPixmap(pix);
1863
1741
        }
1864
1742
    };
1865
1743
    readIcon(16);
1867
1745
    readIcon(48, false);
1868
1746
    readIcon(64, false);
1869
1747
    readIcon(128, false);
1870
 
    if (m_icon.isNull()) {
 
1748
    if (icon.isNull()) {
1871
1749
        // Then try window group
1872
 
        m_icon = group()->icon();
 
1750
        icon = group()->icon();
1873
1751
    }
1874
 
    if (m_icon.isNull() && isTransient()) {
 
1752
    if (icon.isNull() && isTransient()) {
1875
1753
        // Then mainclients
1876
1754
        ClientList mainclients = mainClients();
1877
1755
        for (ClientList::ConstIterator it = mainclients.constBegin();
1878
 
                it != mainclients.constEnd() && m_icon.isNull();
 
1756
                it != mainclients.constEnd() && icon.isNull();
1879
1757
                ++it) {
1880
1758
            if (!(*it)->icon().isNull()) {
1881
 
                m_icon = (*it)->icon();
 
1759
                icon = (*it)->icon();
1882
1760
                break;
1883
1761
            }
1884
1762
        }
1885
1763
    }
1886
 
    if (m_icon.isNull()) {
 
1764
    if (icon.isNull()) {
1887
1765
        // And if nothing else, load icon from classhint or xapp icon
1888
 
        m_icon.addPixmap(KWindowSystem::icon(window(),  32,  32,  true, KWindowSystem::ClassHint | KWindowSystem::XApp, info));
1889
 
        m_icon.addPixmap(KWindowSystem::icon(window(),  16,  16,  true, KWindowSystem::ClassHint | KWindowSystem::XApp, info));
1890
 
        m_icon.addPixmap(KWindowSystem::icon(window(),  64,  64, false, KWindowSystem::ClassHint | KWindowSystem::XApp, info));
1891
 
        m_icon.addPixmap(KWindowSystem::icon(window(), 128, 128, false, KWindowSystem::ClassHint | KWindowSystem::XApp, info));
 
1766
        icon.addPixmap(KWindowSystem::icon(window(),  32,  32,  true, KWindowSystem::ClassHint | KWindowSystem::XApp, info));
 
1767
        icon.addPixmap(KWindowSystem::icon(window(),  16,  16,  true, KWindowSystem::ClassHint | KWindowSystem::XApp, info));
 
1768
        icon.addPixmap(KWindowSystem::icon(window(),  64,  64, false, KWindowSystem::ClassHint | KWindowSystem::XApp, info));
 
1769
        icon.addPixmap(KWindowSystem::icon(window(), 128, 128, false, KWindowSystem::ClassHint | KWindowSystem::XApp, info));
1892
1770
    }
1893
 
    emit iconChanged();
 
1771
    setIcon(icon);
1894
1772
}
1895
1773
 
1896
1774
void Client::getSyncCounter()
1897
1775
{
1898
 
#if HAVE_XCB_SYNC
1899
1776
    if (!Xcb::Extensions::self()->isSyncAvailable())
1900
1777
        return;
1901
1778
 
1931
1808
            }
1932
1809
        }
1933
1810
    }
1934
 
#endif
1935
1811
}
1936
1812
 
1937
1813
/**
1950
1826
                if (!ready_for_painting) {
1951
1827
                    // failed on initial pre-show request
1952
1828
                    setReadyForPainting();
 
1829
                    setupWindowManagementInterface();
1953
1830
                    return;
1954
1831
                }
1955
1832
                // failed during resize
1984
1861
    syncRequest.lastTimestamp = xTime();
1985
1862
}
1986
1863
 
1987
 
bool Client::wantsTabFocus() const
1988
 
{
1989
 
    return (isNormalWindow() || isDialog()) && wantsInput();
1990
 
}
1991
 
 
1992
1864
bool Client::wantsInput() const
1993
1865
{
1994
1866
    return rules()->checkAcceptFocus(info->input() || info->supportsProtocol(NET::TakeFocusProtocol));
1995
1867
}
1996
1868
 
1997
 
bool Client::isSpecialWindow() const
1998
 
{
1999
 
    // TODO
2000
 
    return isDesktop() || isDock() || isSplash() || isToolbar() || isNotification() || isOnScreenDisplay();
2001
 
}
2002
 
 
2003
1869
/**
2004
1870
 * Sets an appropriate cursor shape for the logical mouse position \a m
2005
1871
 */
2056
1922
    }
2057
1923
}
2058
1924
 
2059
 
Client::Position Client::mousePosition(const QPoint& p) const
 
1925
Client::Position Client::mousePosition() const
2060
1926
{
2061
 
    Q_UNUSED(p)
2062
1927
    if (m_decoration) {
2063
1928
        switch (m_decoration->sectionUnderMouse()) {
2064
1929
            case Qt::BottomLeftSection:
2126
1991
    }
2127
1992
}
2128
1993
 
2129
 
void Client::autoRaise()
2130
 
{
2131
 
    workspace()->raiseClient(this);
2132
 
    cancelAutoRaise();
2133
 
}
2134
 
 
2135
 
void Client::cancelAutoRaise()
2136
 
{
2137
 
    delete autoRaiseTimer;
2138
 
    autoRaiseTimer = 0;
2139
 
}
2140
 
 
2141
1994
void Client::debug(QDebug& stream) const
2142
1995
{
2143
1996
    print<QDebug>(stream);
2185
2038
    //if the activities are not synced, and there are existing clients with
2186
2039
    //activities specified, somebody has restarted kwin. we can not validate
2187
2040
    //activities in this case. we need to trust the old values.
2188
 
    if (Activities::self()->serviceStatus() != KActivities::Consumer::Unknown) {
 
2041
    if (Activities::self() && Activities::self()->serviceStatus() != KActivities::Consumer::Unknown) {
2189
2042
        QStringList allActivities = Activities::self()->all();
2190
2043
        if (allActivities.isEmpty()) {
2191
2044
            qCDebug(KWIN_CORE) << "no activities!?!?";
2225
2078
    return QRect(0, 0, width(), height());
2226
2079
}
2227
2080
 
2228
 
Client::Position Client::titlebarPosition() const
2229
 
{
2230
 
    // TODO: still needed, remove?
2231
 
    return PositionTop;
2232
 
}
2233
 
 
2234
2081
Xcb::Property Client::fetchFirstInTabBox() const
2235
2082
{
2236
2083
    return Xcb::Property(false, m_client, atoms->kde_first_in_window_list,
2256
2103
 
2257
2104
void Client::readColorScheme(Xcb::StringProperty &property)
2258
2105
{
2259
 
    QString path = QString::fromUtf8(property);
2260
 
    path = rules()->checkDecoColor(path);
2261
 
 
2262
 
    if (path.isEmpty()) {
2263
 
        path = QStringLiteral("kdeglobals");
2264
 
    }
2265
 
 
2266
 
    if (!m_palette || m_colorScheme != path) {
2267
 
        m_colorScheme = path;
2268
 
 
2269
 
        if (m_palette) {
2270
 
            disconnect(m_palette.get(), &Decoration::DecorationPalette::changed, this, &Client::handlePaletteChange);
2271
 
        }
2272
 
 
2273
 
        auto it = s_palettes.find(m_colorScheme);
2274
 
 
2275
 
        if (it == s_palettes.end() || it->expired()) {
2276
 
            m_palette = std::make_shared<Decoration::DecorationPalette>(m_colorScheme);
2277
 
            if (m_palette->isValid()) {
2278
 
                s_palettes[m_colorScheme] = m_palette;
2279
 
            } else {
2280
 
                if (!s_defaultPalette) {
2281
 
                    s_defaultPalette = std::make_shared<Decoration::DecorationPalette>(QStringLiteral("kdeglobals"));
2282
 
                    s_palettes[QStringLiteral("kdeglobals")] = s_defaultPalette;
2283
 
                }
2284
 
 
2285
 
                m_palette = s_defaultPalette;
2286
 
            }
2287
 
 
2288
 
            if (m_colorScheme == QStringLiteral("kdeglobals")) {
2289
 
                s_defaultPalette = m_palette;
2290
 
            }
2291
 
        } else {
2292
 
            m_palette = it->lock();
2293
 
        }
2294
 
 
2295
 
        connect(m_palette.get(), &Decoration::DecorationPalette::changed, this, &Client::handlePaletteChange);
2296
 
 
2297
 
        emit paletteChanged(palette());
2298
 
        triggerDecorationRepaint();
2299
 
    }
 
2106
    AbstractClient::updateColorScheme(rules()->checkDecoColor(QString::fromUtf8(property)));
2300
2107
}
2301
2108
 
2302
2109
void Client::updateColorScheme()
2305
2112
    readColorScheme(property);
2306
2113
}
2307
2114
 
2308
 
void Client::handlePaletteChange()
2309
 
{
2310
 
    emit paletteChanged(palette());
2311
 
    triggerDecorationRepaint();
2312
 
}
2313
 
 
2314
2115
bool Client::isClient() const
2315
2116
{
2316
2117
    return true;
2433
2234
void Client::addDamage(const QRegion &damage)
2434
2235
{
2435
2236
    if (!ready_for_painting) { // avoid "setReadyForPainting()" function calling overhead
2436
 
        if (syncRequest.counter == XCB_NONE)   // cannot detect complete redraw, consider done now
 
2237
        if (syncRequest.counter == XCB_NONE) {  // cannot detect complete redraw, consider done now
2437
2238
            setReadyForPainting();
 
2239
            setupWindowManagementInterface();
 
2240
        }
2438
2241
    }
2439
2242
    Toplevel::addDamage(damage);
2440
2243
}
2441
2244
 
 
2245
bool Client::belongsToSameApplication(const AbstractClient *other, bool active_hack) const
 
2246
{
 
2247
    const Client *c2 = dynamic_cast<const Client*>(other);
 
2248
    if (!c2) {
 
2249
        return false;
 
2250
    }
 
2251
    return Client::belongToSameApplication(this, c2, active_hack);
 
2252
}
 
2253
 
 
2254
bool Client::processDecorationButtonPress(QMouseEvent *event)
 
2255
{
 
2256
    return processDecorationButtonPress(qtToX11Button(event->button()), 0,
 
2257
                                        event->x(), event->y(),
 
2258
                                        event->globalX(), event->globalY());
 
2259
}
 
2260
 
 
2261
void Client::processDecorationButtonRelease(QMouseEvent *event)
 
2262
{
 
2263
    if (m_decoration) {
 
2264
        if (!event->isAccepted() && m_decoration->titleBar().contains(event->pos()) && event->button() == Qt::LeftButton) {
 
2265
            m_decorationDoubleClickTimer.start();
 
2266
        }
 
2267
    }
 
2268
 
 
2269
    if (event->buttons() == Qt::NoButton) {
 
2270
        buttonDown = false;
 
2271
        stopDelayedMoveResize();
 
2272
        if (moveResizeMode) {
 
2273
            finishMoveResize(false);
 
2274
            mode = mousePosition();
 
2275
        }
 
2276
        updateCursor();
 
2277
    }
 
2278
}
 
2279
 
 
2280
void Client::processDecorationMove()
 
2281
{
 
2282
    if (buttonDown) {
 
2283
        return;
 
2284
    }
 
2285
    // TODO: handle modifiers
 
2286
    Position newmode = mousePosition();
 
2287
    if (newmode != mode) {
 
2288
        mode = newmode;
 
2289
        updateCursor();
 
2290
    }
 
2291
}
 
2292
 
2442
2293
} // namespace
2443
2294
 
2444
2295
#include "client.moc"