aboutsummaryrefslogtreecommitdiff
path: root/src/FluxboxHandler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FluxboxHandler.cc')
-rw-r--r--src/FluxboxHandler.cc204
1 files changed, 204 insertions, 0 deletions
diff --git a/src/FluxboxHandler.cc b/src/FluxboxHandler.cc
new file mode 100644
index 0000000..32bfcc8
--- /dev/null
+++ b/src/FluxboxHandler.cc
@@ -0,0 +1,204 @@
1// FluxboxHandler.cc for FbPager
2// Copyright (c) 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#include "FluxboxHandler.hh"
23
24#include "Pager.hh"
25#include "WindowHint.hh"
26#include "FbRootWindow.hh"
27#include "ClientWindow.hh"
28
29#include "FbTk/App.hh"
30
31#include <X11/Xutil.h>
32
33#include <iostream>
34using namespace std;
35
36namespace {
37
38void sendClientMessage(FbTk::FbWindow &src,
39 FbTk::FbWindow &dest,
40 Atom the_atom,
41 unsigned long data1, unsigned long data2 = 0,
42 unsigned long data3 = 0, unsigned long data4 = 0) {
43 // fill in client structure
44 XEvent clientevent;
45 clientevent.xclient.display = FbTk::App::instance()->display();
46 clientevent.xclient.type = ClientMessage;
47 clientevent.xclient.window = dest.window();
48 clientevent.xclient.message_type = the_atom;
49 clientevent.xclient.format = 32;
50 clientevent.xclient.data.l[0] = data1;
51 clientevent.xclient.data.l[1] = data2;
52 clientevent.xclient.data.l[2] = data3;
53 clientevent.xclient.data.l[3] = data4;
54 // send event to root window
55 src.sendEvent(false, SubstructureRedirectMask, clientevent);
56}
57
58} // end anonymous namespace
59
60struct FluxboxHints {
61 unsigned long flags, attrib, workspace, stack, decoration;
62 enum Attrib {
63 ATTRIB_SHADED = 0x01,
64 ATTRIB_STICK = 0x08,
65 ATTRIB_WORKSPACE = 0x10,
66 ATTRIB_DECOR = 0x40
67 };
68 enum Decor { NO_DECOR = 0 };
69};
70
71namespace FbPager {
72
73FluxboxHandler *FluxboxHandler::s_handler = 0;
74
75FluxboxHandler::FluxboxHandler():
76 m_fbatoms(FbTk::App::instance()->display()) {
77 s_handler = this;
78}
79
80void FluxboxHandler::setFocus(FbTk::FbWindow &client) {
81 FbRootWindow root(client.screenNumber());
82 sendClientMessage(root, client,
83 m_fbatoms.getFluxboxChangeWindowFocusAtom(), 0);
84}
85
86void FluxboxHandler::sendToWorkspace(FbTk::FbWindow &client, int workspace) {
87 FbRootWindow root(client.screenNumber());
88 sendClientMessage(root, client,
89 m_fbatoms.getFluxboxChangeAttributesAtom(),
90 FluxboxHints::ATTRIB_WORKSPACE,
91 0,
92 workspace);
93}
94
95void FluxboxHandler::closeWindow(FbTk::FbWindow &win) {
96}
97
98
99bool FluxboxHandler::clientMessage(Pager &pager, XClientMessageEvent &event) {
100 const FbAtoms &fbatoms = *FbAtoms::instance();
101 if (event.data.l[0] == fbatoms.getFluxboxNotifyWorkspaceCountAtom()) {
102 pager.updateWorkspaceCount(event.data.l[1]);
103 return true;
104 } else if (event.data.l[0] == fbatoms.getFluxboxNotifyCurrentWorkspaceAtom()) {
105 pager.setCurrentWorkspace(event.data.l[1]);
106 return true;
107 } else if (event.data.l[0] == fbatoms.getFluxboxNotifyWindowAddAtom()) {
108 pager.addWindow(event.data.l[1], event.data.l[2]);
109 return true;
110 } else if (event.data.l[0] == fbatoms.getFluxboxNotifyWindowDelAtom()) {
111 pager.removeWindow(event.data.l[1]);
112 return true;
113 } else if (event.data.l[0] == fbatoms.getFluxboxNotifyWindowRaiseAtom()) {
114 pager.raiseWindow(event.data.l[1]);
115 return true;
116 } else if (event.data.l[0] == fbatoms.getFluxboxNotifyWindowLowerAtom()) {
117 pager.lowerWindow(event.data.l[1]);
118 return true;
119 } else if (event.data.l[0] == fbatoms.getFluxboxNotifyWindowFocusAtom()) {
120 pager.setFocusedWindow(event.data.l[1]);
121 return true;
122 }
123
124 return false;
125}
126
127void FluxboxHandler::changeWorkspace(int screen_num, int workspace) {
128 FbRootWindow root(screen_num);
129 sendClientMessage(root, root, FbAtoms::instance()->getFluxboxChangeWorkspaceAtom(), workspace);
130}
131
132void FluxboxHandler::setHints(FbTk::FbWindow &win, WindowHint &hints) {
133 FluxboxHints net_hints;
134 net_hints.decoration = (hints.flags() & WindowHint::WHINT_NO_DECOR) ? FluxboxHints::NO_DECOR : 1;
135 net_hints.attrib = (hints.flags() & WindowHint::WHINT_STICKY) ? FluxboxHints::ATTRIB_STICK : 0;
136 // use Decoration and sticky flag
137 net_hints.flags = FluxboxHints::ATTRIB_DECOR | FluxboxHints::ATTRIB_STICK;
138 Atom hint_atom = m_fbatoms.getFluxboxHintsAtom();
139 win.changeProperty(hint_atom, hint_atom,
140 32, PropModeReplace,
141 (unsigned char *)(&net_hints),
142 5); // number of fluxbox hints in the structure
143}
144
145void FluxboxHandler::getHints(const FbTk::FbWindow &win, WindowHint &hint) const {
146 Atom real_type;
147 int format;
148 unsigned long num_elements, not_used;
149 FluxboxHints *win_hints;
150
151 if (!win.property(m_fbatoms.getFluxboxAttributesAtom(), 0L,
152 5, // five elements in our structure
153 false,
154 m_fbatoms.getFluxboxAttributesAtom(),
155 &real_type, &format, &num_elements, &not_used,
156 (unsigned char**)&win_hints) ||
157 num_elements != 5) // must have five elements
158 return; // failure
159
160 hint.setWorkspace(win_hints->workspace);
161
162 // get shaded state
163 bool shaded = false;
164 if (win_hints->flags & FluxboxHints::ATTRIB_SHADED)
165 hint.add(WindowHint::WHINT_SHADED);
166
167 // get sticky state
168 bool sticky = false;
169 if (win_hints->flags & FluxboxHints::ATTRIB_STICK)
170 hint.add(WindowHint::WHINT_STICKY);
171
172 // get icon state
173 long *state;
174 bool iconified = false;
175 if (!win.property(m_fbatoms.getWMStateAtom(), 0, 1,
176 False, m_fbatoms.getWMStateAtom(),
177 &real_type, &format, &num_elements, &not_used,
178 (unsigned char**)&state) || state == 0)
179 cerr<<"Warning: Couldn't get WM_STATE property"<<endl;
180 else if (state[0] == IconicState)
181 hint.add(WindowHint::WHINT_ICONIC);
182
183 return;
184}
185
186int FluxboxHandler::numberOfWorkspaces(int screen_num) const {
187 Atom real_type;
188 int format;
189 unsigned long num_elements, not_used;
190 unsigned char *data = 0;
191 Display *disp = FbTk::App::instance()->display();
192 if (XGetWindowProperty(disp, RootWindow(disp, screen_num),
193 m_fbatoms.getFluxboxNotifyWorkspaceCountAtom(), 0, 1,
194 False, 0,
195 &real_type, &format, &num_elements, &not_used,
196 (unsigned char**)&data) == Success) {
197 if (data != 0)
198 return static_cast<int>(*data);
199 }
200
201 return 0;
202}
203
204} // end namespace FbPager