aboutsummaryrefslogtreecommitdiff
path: root/src/Workspace.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Workspace.cc')
-rw-r--r--src/Workspace.cc339
1 files changed, 339 insertions, 0 deletions
diff --git a/src/Workspace.cc b/src/Workspace.cc
new file mode 100644
index 0000000..8c46b43
--- /dev/null
+++ b/src/Workspace.cc
@@ -0,0 +1,339 @@
1// Workspace.cc for FbPager
2// Copyright (c) 2003-2004 Henrik Kinnunen (fluxgen at users.sourceforge.net)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id$
23
24#include "Workspace.hh"
25
26#include "FbTk/App.hh"
27#include "FbTk/Color.hh"
28#include "FbTk/EventManager.hh"
29
30#include "ScaleWindowToWindow.hh"
31#include "FbRootWindow.hh"
32
33#include <X11/Xutil.h>
34
35#include <iostream>
36#include <algorithm>
37#include <functional>
38using namespace std;
39
40namespace FbPager {
41
42Window Workspace::s_focused_window = 0;
43
44Workspace::Workspace(FbTk::EventHandler &evh,
45 FbTk::FbWindow &parent, unsigned int width, unsigned int height,
46 const FbTk::Color &focused_win_color,
47 const FbTk::Color &wincolor, const FbTk::Color &border_color,
48 const FbTk::Color &background_color,
49 const char *name,
50 const bool use_pixmap,
51 const int window_border_width):
52 m_name(name ? name : ""),
53 m_window(parent,
54 0, 0, // position
55 width, height, // size
56 ButtonPressMask | ButtonReleaseMask | ExposureMask | ButtonMotionMask),
57 m_eventhandler(evh),
58 m_window_color(wincolor),
59 m_focused_window_color(focused_win_color),
60 m_window_bordercolor(border_color),
61 m_focused_window(0),
62 m_use_pixmap(use_pixmap),
63 m_window_border_width(window_border_width) {
64
65 m_window.setBackgroundColor(background_color);
66 FbTk::EventManager::instance()->add(evh, m_window);
67}
68
69Workspace::~Workspace() {
70 WindowList::iterator it = m_windowlist.begin();
71 WindowList::iterator it_end = m_windowlist.end();
72 for (; it != it_end; ++it) {
73 FbTk::EventManager::instance()->remove(*(*it).second);
74 FbTk::EventManager::instance()->remove((*it).first);
75 delete (*it).second;
76 }
77
78 FbTk::EventManager::instance()->remove(m_window);
79}
80
81void Workspace::add(Window win) {
82 FbTk::FbWindow *fbwin = find(win);
83 if (fbwin != 0)
84 delete fbwin;
85
86
87 fbwin = new FbTk::FbWindow(m_window, // parent
88 0, 0, // pos
89 10, 10, // size
90 // event mask
91 ExposureMask);
92 // fbwin->setAlpha(m_window.alpha());
93
94 XSelectInput(FbTk::App::instance()->display(), win,
95 PropertyChangeMask | // for shade/iconic state
96 StructureNotifyMask // for pos and size
97 );
98 // add to event manager
99 FbTk::EventManager::instance()->add(m_eventhandler, *fbwin);
100 FbTk::EventManager::instance()->add(m_eventhandler, win);
101
102 // add window to list
103 m_windowlist[win] = fbwin;
104
105 // update pos and size
106 updateGeometry(win);
107
108 fbwin->show();
109 fbwin->setBorderWidth(m_window_border_width);
110 fbwin->setBorderColor(m_window_bordercolor);
111
112 updateBackground(win, m_window_color);
113}
114
115void Workspace::resize(unsigned int width, unsigned int height) {
116 m_window.resize(width, height);
117 WindowList::iterator it = m_windowlist.begin();
118 WindowList::iterator it_end = m_windowlist.end();
119 for (; it != it_end; ++it) {
120 updateGeometry((*it).first);
121 }
122}
123
124
125void Workspace::shadeWindow(Window win) {
126 FbTk::FbWindow *fbwin = find(win);
127 if (fbwin == 0)
128 return;
129
130 fbwin->resize(fbwin->width(), m_window.height()/30);
131}
132
133void Workspace::unshadeWindow(Window win) {
134 updateGeometry(win);
135}
136
137void Workspace::iconifyWindow(Window win) {
138 FbTk::FbWindow *fbwin = find(win);
139 if (fbwin == 0)
140 return;
141
142 fbwin->hide();
143}
144
145void Workspace::deiconifyWindow(Window win) {
146 FbTk::FbWindow *fbwin = find(win);
147 if (fbwin != 0)
148 return;
149 fbwin->show();
150}
151
152void Workspace::lowerWindow(Window win) {
153 FbTk::FbWindow *fbwin = find(win);
154 if (fbwin == 0)
155 return;
156 fbwin->lower();
157}
158
159void Workspace::raiseWindow(Window win) {
160 FbTk::FbWindow *fbwin = find(win);
161 if (fbwin == 0)
162 return;
163 fbwin->raise();
164}
165
166void Workspace::setWindowColor(const std::string &focused,
167 const std::string &unfocused,
168 const std::string &bordercolor_str) {
169 m_window_color = FbTk::Color(unfocused.c_str(), m_window.screenNumber());
170 m_focused_window_color = FbTk::Color(focused.c_str(), m_window.screenNumber());
171 m_window_bordercolor = FbTk::Color(bordercolor_str.c_str(), m_window.screenNumber());
172
173 WindowList::iterator it = m_windowlist.begin();
174 WindowList::iterator it_end = m_windowlist.end();
175 for (; it != it_end; ++it) {
176 (*it).second->setBorderColor(m_window_bordercolor);
177 updateBackground((*it).first, m_window_color);
178 }
179 updateFocusedWindow();
180}
181
182
183void Workspace::setAlpha(unsigned char alpha) {
184 m_window.setAlpha(alpha);
185 WindowList::iterator it = m_windowlist.begin();
186 WindowList::iterator it_end = m_windowlist.end();
187 for (; it != it_end; ++it) {
188 (*it).second->setAlpha(alpha);
189 }
190}
191
192void Workspace::clearWindows() {
193 m_window.clear();
194 WindowList::iterator it = m_windowlist.begin();
195 WindowList::iterator it_end = m_windowlist.end();
196 for (; it != it_end; ++it) {
197 if (m_use_pixmap) {
198 updateBackground((*it).first,m_window_color);
199 }
200 (*it).second->clear();
201 }
202}
203
204void Workspace::remove(Window win) {
205 FbTk::FbWindow *fbwin = find(win);
206 if (fbwin == 0)
207 return;
208 FbTk::EventManager::instance()->remove(*fbwin);
209 // FbTk::EventManager::instance()->remove(win);
210
211 delete fbwin;
212
213 if (fbwin == m_focused_window)
214 m_focused_window = 0;
215
216 m_windowlist.erase(win);
217}
218
219ClientWindow Workspace::findClient(const FbTk::FbWindow &win) const {
220 WindowList::const_iterator it = m_windowlist.begin();
221 WindowList::const_iterator it_end = m_windowlist.end();
222 for (; it != it_end; ++it) {
223 if (*(*it).second == win)
224 return ClientWindow((*it).first);
225 }
226 return ClientWindow(0);
227}
228
229FbTk::FbWindow *Workspace::find(Window win) {
230 WindowList::iterator it = m_windowlist.begin();
231 WindowList::iterator it_end = m_windowlist.end();
232 for (; it != it_end; ++it) {
233 if ((*it).second->window() == win ||
234 (*it).first == win)
235 return it->second;
236 }
237 return 0;
238}
239
240const FbTk::FbWindow *Workspace::find(Window win) const {
241 WindowList::const_iterator it = m_windowlist.begin();
242 WindowList::const_iterator it_end = m_windowlist.end();
243 for (; it != it_end; ++it) {
244 if ((*it).second->window() == win ||
245 (*it).first == win)
246 return it->second;
247 }
248 return 0;
249}
250
251void Workspace::updateFocusedWindow() {
252 if (s_focused_window == 0)
253 return;
254
255 FbTk::FbWindow *fbwin = find(s_focused_window);
256 if (fbwin == m_focused_window)
257 return;
258
259 if (m_focused_window != 0) {
260
261 updateBackground(m_focused_window->window(), m_window_color);
262 m_focused_window->clear();
263 }
264
265 if (fbwin == 0) {
266 m_focused_window = 0;
267 return;
268 }
269
270 WindowList::const_iterator it = m_windowlist.begin();
271 WindowList::const_iterator it_end = m_windowlist.end();
272 for (; it != it_end; ++it) {
273 if ((*it).second == fbwin )
274 break;
275 }
276
277 if (it == it_end)
278 return;
279
280 updateBackground((*it).first, m_focused_window_color);
281 fbwin->clear();
282 m_focused_window = fbwin;
283}
284
285void Workspace::updateGeometry(Window win) {
286
287 FbTk::FbWindow* fbwin= find(win);
288 if (!fbwin)
289 return;
290
291 int x = 0, y = 0;
292 Window child;
293 ClientWindow client(win);
294 FbRootWindow rootwin(m_window.screenNumber());
295 rootwin.translateCoordinates(client,
296 client.x(), client.y(),
297 x, y,
298 child);
299 x = -x;
300 y = -y;
301 unsigned int w = client.width(), h = client.height();
302 scaleFromWindowToWindow(rootwin, m_window, x, y);
303 scaleFromWindowToWindow(rootwin, m_window, w, h);
304 w -= fbwin->borderWidth();
305 if (w == 0)
306 w = 1;
307 if (h == 0)
308 h = 1;
309
310 fbwin->moveResize(x, y, w, h);
311 updateBackground(win, m_window_color);
312}
313
314void Workspace::updateBackground(Window win, const FbTk::Color &bg_color) {
315
316 FbTk::FbWindow* fbwin= find(win);
317 if (!fbwin )
318 return;
319
320
321 if (m_use_pixmap) {
322 XWMHints *hints = XGetWMHints(FbTk::App::instance()->display(), win);
323 if (hints && (hints->flags & IconPixmapHint) && hints->icon_pixmap != 0) {
324 FbTk::FbPixmap fbpix;
325 fbpix.copy(hints->icon_pixmap);
326 fbpix.scale(fbwin->width(), fbwin->height());
327 fbwin->setBackgroundPixmap(fbpix.drawable());
328 }
329 else
330 fbwin->setBackgroundColor(bg_color);
331
332 XFree(hints);
333 }
334 else
335 fbwin->setBackgroundColor(bg_color);
336}
337
338}; // end namespace FbPager
339