1/********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5Copyright (C) 2013 Martin Gräßlin <mgraesslin@kde.org>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19*********************************************************************/
20#include "screens.h"
21#include "client.h"
22#include "cursor.h"
23#include "settings.h"
24#include "workspace.h"
25
26#include <QApplication>
27#include <QDesktopWidget>
28#include <QTimer>
29
30namespace KWin
31{
32
33KWIN_SINGLETON_FACTORY_FACTORED(Screens, DesktopWidgetScreens)
34
35Screens::Screens(QObject *parent)
36 : QObject(parent)
37 , m_count(0)
38 , m_current(0)
39 , m_currentFollowsMouse(false)
40 , m_changedTimer(new QTimer(this))
41{
42 m_changedTimer->setSingleShot(true);
43 m_changedTimer->setInterval(100);
44 connect(m_changedTimer, SIGNAL(timeout()), SLOT(updateCount()));
45 connect(m_changedTimer, SIGNAL(timeout()), SIGNAL(changed()));
46
47 Settings settings;
48 settings.setDefaults();
49 m_currentFollowsMouse = settings.activeMouseScreen();
50}
51
52Screens::~Screens()
53{
54 s_self = NULL;
55}
56
57void Screens::reconfigure()
58{
59 if (!m_config) {
60 return;
61 }
62 Settings settings(m_config);
63 settings.readConfig();
64 setCurrentFollowsMouse(settings.activeMouseScreen());
65}
66
67void Screens::setCount(int count)
68{
69 if (m_count == count) {
70 return;
71 }
72 const int previous = m_count;
73 m_count = count;
74 emit countChanged(previous, count);
75}
76
77void Screens::setCurrent(int current)
78{
79 if (m_current == current) {
80 return;
81 }
82 m_current = current;
83}
84
85void Screens::setCurrent(const QPoint &pos)
86{
87 setCurrent(number(pos));
88}
89
90void Screens::setCurrent(const Client *c)
91{
92 if (!c->isActive()) {
93 return;
94 }
95 if (!c->isOnScreen(m_current)) {
96 setCurrent(c->screen());
97 }
98}
99
100void Screens::setCurrentFollowsMouse(bool follows)
101{
102 if (m_currentFollowsMouse == follows) {
103 return;
104 }
105 m_currentFollowsMouse = follows;
106}
107
108int Screens::current() const
109{
110 if (m_currentFollowsMouse) {
111 return number(Cursor::pos());
112 }
113 Client *client = Workspace::self()->activeClient();
114 if (client && !client->isOnScreen(m_current)) {
115 return client->screen();
116 }
117 return m_current;
118}
119
120int Screens::intersecting(const QRect &r) const
121{
122 int cnt = 0;
123 for (int i = 0; i < count(); ++i) {
124 if (geometry(i).intersects(r)) {
125 ++cnt;
126 }
127 }
128 return cnt;
129}
130
131DesktopWidgetScreens::DesktopWidgetScreens(QObject *parent)
132 : Screens(parent)
133 , m_desktop(QApplication::desktop())
134{
135 connect(m_desktop, SIGNAL(screenCountChanged(int)), SLOT(startChangedTimer()));
136 connect(m_desktop, SIGNAL(resized(int)), SLOT(startChangedTimer()));
137 updateCount();
138}
139
140DesktopWidgetScreens::~DesktopWidgetScreens()
141{
142}
143
144QRect DesktopWidgetScreens::geometry(int screen) const
145{
146 if (Screens::self()->isChanging())
147 const_cast<DesktopWidgetScreens*>(this)->updateCount();
148 return m_desktop->screenGeometry(screen);
149}
150
151int DesktopWidgetScreens::number(const QPoint &pos) const
152{
153 if (Screens::self()->isChanging())
154 const_cast<DesktopWidgetScreens*>(this)->updateCount();
155 return m_desktop->screenNumber(pos);
156}
157
158void DesktopWidgetScreens::updateCount()
159{
160 setCount(m_desktop->screenCount());
161}
162
163} // namespace
164