// FluxboxHandler.cc for FbPager
// Copyright (c) 2004 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "FluxboxHandler.hh"
#include "Pager.hh"
#include "WindowHint.hh"
#include "FbRootWindow.hh"
#include "ClientWindow.hh"
#include "FbTk/App.hh"
#include <X11/Xutil.h>
#include <iostream>
using namespace std;
namespace {
void sendClientMessage(FbTk::FbWindow &src,
FbTk::FbWindow &dest,
Atom the_atom,
unsigned long data1, unsigned long data2 = 0,
unsigned long data3 = 0, unsigned long data4 = 0) {
// fill in client structure
XEvent clientevent;
clientevent.xclient.display = FbTk::App::instance()->display();
clientevent.xclient.type = ClientMessage;
clientevent.xclient.window = dest.window();
clientevent.xclient.message_type = the_atom;
clientevent.xclient.format = 32;
clientevent.xclient.data.l[0] = data1;
clientevent.xclient.data.l[1] = data2;
clientevent.xclient.data.l[2] = data3;
clientevent.xclient.data.l[3] = data4;
// send event to root window
src.sendEvent(false, SubstructureRedirectMask, clientevent);
}
} // end anonymous namespace
struct FluxboxHints {
unsigned long flags, attrib, workspace, stack, decoration;
enum Attrib {
ATTRIB_SHADED = 0x01,
ATTRIB_STICK = 0x08,
ATTRIB_WORKSPACE = 0x10,
ATTRIB_DECOR = 0x40
};
enum Decor { NO_DECOR = 0 };
};
namespace FbPager {
FluxboxHandler *FluxboxHandler::s_handler = 0;
FluxboxHandler::FluxboxHandler():
m_fbatoms(FbTk::App::instance()->display()) {
s_handler = this;
}
void FluxboxHandler::setFocus(FbTk::FbWindow &client) {
FbRootWindow root(client.screenNumber());
sendClientMessage(root, client,
m_fbatoms.getFluxboxChangeWindowFocusAtom(), 0);
}
void FluxboxHandler::sendToWorkspace(FbTk::FbWindow &client, int workspace) {
FbRootWindow root(client.screenNumber());
sendClientMessage(root, client,
m_fbatoms.getFluxboxChangeAttributesAtom(),
FluxboxHints::ATTRIB_WORKSPACE,
0,
workspace);
}
void FluxboxHandler::closeWindow(FbTk::FbWindow &win) {
}
bool FluxboxHandler::clientMessage(Pager &pager, XClientMessageEvent &event) {
const FbAtoms &fbatoms = *FbAtoms::instance();
if (event.data.l[0] == fbatoms.getFluxboxNotifyWorkspaceCountAtom()) {
pager.updateWorkspaceCount(event.data.l[1]);
return true;
} else if (event.data.l[0] == fbatoms.getFluxboxNotifyCurrentWorkspaceAtom()) {
pager.setCurrentWorkspace(event.data.l[1]);
return true;
} else if (event.data.l[0] == fbatoms.getFluxboxNotifyWindowAddAtom()) {
pager.addWindow(event.data.l[1], event.data.l[2]);
return true;
} else if (event.data.l[0] == fbatoms.getFluxboxNotifyWindowDelAtom()) {
pager.removeWindow(event.data.l[1]);
return true;
} else if (event.data.l[0] == fbatoms.getFluxboxNotifyWindowRaiseAtom()) {
pager.raiseWindow(event.data.l[1]);
return true;
} else if (event.data.l[0] == fbatoms.getFluxboxNotifyWindowLowerAtom()) {
pager.lowerWindow(event.data.l[1]);
return true;
} else if (event.data.l[0] == fbatoms.getFluxboxNotifyWindowFocusAtom()) {
pager.setFocusedWindow(event.data.l[1]);
return true;
}
return false;
}
void FluxboxHandler::changeWorkspace(int screen_num, int workspace) {
FbRootWindow root(screen_num);
sendClientMessage(root, root, FbAtoms::instance()->getFluxboxChangeWorkspaceAtom(), workspace);
}
void FluxboxHandler::setHints(FbTk::FbWindow &win, WindowHint &hints) {
FluxboxHints net_hints;
net_hints.decoration = (hints.flags() & WindowHint::WHINT_NO_DECOR) ? FluxboxHints::NO_DECOR : 1;
net_hints.attrib = (hints.flags() & WindowHint::WHINT_STICKY) ? FluxboxHints::ATTRIB_STICK : 0;
// use Decoration and sticky flag
net_hints.flags = FluxboxHints::ATTRIB_DECOR | FluxboxHints::ATTRIB_STICK;
Atom hint_atom = m_fbatoms.getFluxboxHintsAtom();
win.changeProperty(hint_atom, hint_atom,
32, PropModeReplace,
(unsigned char *)(&net_hints),
5); // number of fluxbox hints in the structure
}
void FluxboxHandler::getHints(const FbTk::FbWindow &win, WindowHint &hint) const {
Atom real_type;
int format;
unsigned long num_elements, not_used;
FluxboxHints *win_hints;
if (!win.property(m_fbatoms.getFluxboxAttributesAtom(), 0L,
5, // five elements in our structure
false,
m_fbatoms.getFluxboxAttributesAtom(),
&real_type, &format, &num_elements, ¬_used,
(unsigned char**)&win_hints) ||
num_elements != 5) // must have five elements
return; // failure
hint.setWorkspace(win_hints->workspace);
// get shaded state
bool shaded = false;
if (win_hints->flags & FluxboxHints::ATTRIB_SHADED)
hint.add(WindowHint::WHINT_SHADED);
// get sticky state
bool sticky = false;
if (win_hints->flags & FluxboxHints::ATTRIB_STICK)
hint.add(WindowHint::WHINT_STICKY);
// get icon state
long *state;
bool iconified = false;
if (!win.property(m_fbatoms.getWMStateAtom(), 0, 1,
False, m_fbatoms.getWMStateAtom(),
&real_type, &format, &num_elements, ¬_used,
(unsigned char**)&state) || state == 0)
cerr<<"Warning: Couldn't get WM_STATE property"<<endl;
else if (state[0] == IconicState)
hint.add(WindowHint::WHINT_ICONIC);
return;
}
int FluxboxHandler::numberOfWorkspaces(int screen_num) const {
Atom real_type;
int format;
unsigned long num_elements, not_used;
unsigned char *data = 0;
Display *disp = FbTk::App::instance()->display();
if (XGetWindowProperty(disp, RootWindow(disp, screen_num),
m_fbatoms.getFluxboxNotifyWorkspaceCountAtom(), 0, 1,
False, 0,
&real_type, &format, &num_elements, ¬_used,
(unsigned char**)&data) == Success) {
if (data != 0)
return static_cast<int>(*data);
}
return 0;
}
} // end namespace FbPager
syntax highlighted by Code2HTML, v. 0.9.1