2002-11-14 00:23:19 +00:00
|
|
|
// Slit.cc for fluxbox
|
2003-01-12 17:56:15 +00:00
|
|
|
// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
|
2002-11-14 00:23:19 +00:00
|
|
|
//
|
2001-12-11 20:47:02 +00:00
|
|
|
// Slit.cc for Blackbox - an X11 Window manager
|
2003-01-12 17:56:15 +00:00
|
|
|
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
|
2001-12-11 20:47:02 +00:00
|
|
|
//
|
|
|
|
// 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,
|
2003-01-12 17:56:15 +00:00
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
2001-12-11 20:47:02 +00:00
|
|
|
// 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.
|
|
|
|
|
2003-05-15 12:00:46 +00:00
|
|
|
// $Id: Slit.cc,v 1.53 2003/05/15 12:00:45 fluxgen Exp $
|
2003-01-12 17:56:15 +00:00
|
|
|
|
|
|
|
#include "Slit.hh"
|
2002-04-08 18:58:47 +00:00
|
|
|
|
2002-03-11 12:29:57 +00:00
|
|
|
//use GNU extensions
|
2001-12-11 20:47:02 +00:00
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#endif // _GNU_SOURCE
|
|
|
|
|
2002-10-13 21:47:54 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2003-05-04 20:50:15 +00:00
|
|
|
#include "config.h"
|
2001-12-11 20:47:02 +00:00
|
|
|
#endif // HAVE_CONFIG_H
|
|
|
|
|
|
|
|
#include "i18n.hh"
|
|
|
|
#include "Screen.hh"
|
2002-11-30 20:29:27 +00:00
|
|
|
#include "ImageControl.hh"
|
2003-01-12 17:56:15 +00:00
|
|
|
#include "RefCount.hh"
|
|
|
|
#include "SimpleCommand.hh"
|
|
|
|
#include "BoolMenuItem.hh"
|
|
|
|
#include "EventManager.hh"
|
|
|
|
#include "MacroCommand.hh"
|
2003-02-18 15:11:12 +00:00
|
|
|
#include "LayerMenu.hh"
|
|
|
|
#include "fluxbox.hh"
|
|
|
|
#include "XLayer.hh"
|
2003-04-25 10:46:07 +00:00
|
|
|
#include "RootTheme.hh"
|
|
|
|
#include "FbTk/Theme.hh"
|
2003-05-06 01:45:17 +00:00
|
|
|
#include "FbMenu.hh"
|
2003-05-13 21:12:18 +00:00
|
|
|
#include "Transparent.hh"
|
|
|
|
#include "IntResMenuItem.hh"
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-02-04 22:33:09 +00:00
|
|
|
#include <algorithm>
|
2002-05-29 06:21:59 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <cassert>
|
2002-02-04 22:33:09 +00:00
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
#ifdef HAVE_SYS_STAT_H
|
2003-01-12 17:56:15 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2002-05-29 06:21:59 +00:00
|
|
|
#endif // HAVE_SYS_STAT_H
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
#include <X11/Xatom.h>
|
2002-05-29 06:21:59 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <algorithm>
|
|
|
|
using namespace std;
|
2002-05-29 06:21:59 +00:00
|
|
|
namespace {
|
2002-11-14 00:23:19 +00:00
|
|
|
|
|
|
|
void getWMName(BScreen *screen, Window window, std::string& name) {
|
2002-12-01 13:42:15 +00:00
|
|
|
name = "";
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (screen == 0 || window == None)
|
|
|
|
return;
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
Display *display = FbTk::App::instance()->display();
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
XTextProperty text_prop;
|
|
|
|
char **list;
|
|
|
|
int num;
|
|
|
|
I18n *i18n = I18n::instance();
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (XGetWMName(display, window, &text_prop)) {
|
|
|
|
if (text_prop.value && text_prop.nitems > 0) {
|
|
|
|
if (text_prop.encoding != XA_STRING) {
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
text_prop.nitems = strlen((char *) text_prop.value);
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if ((XmbTextPropertyToTextList(display, &text_prop,
|
|
|
|
&list, &num) == Success) &&
|
|
|
|
(num > 0) && *list) {
|
|
|
|
name = static_cast<char *>(*list);
|
|
|
|
XFreeStringList(list);
|
|
|
|
} else
|
|
|
|
name = (char *)text_prop.value;
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
} else
|
|
|
|
name = (char *)text_prop.value;
|
|
|
|
} else { // default name
|
|
|
|
name = i18n->getMessage(
|
2003-01-12 17:56:15 +00:00
|
|
|
FBNLS::WindowSet, FBNLS::WindowUnnamed,
|
|
|
|
"Unnamed");
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// default name
|
|
|
|
name = i18n->getMessage(
|
2003-01-12 17:56:15 +00:00
|
|
|
FBNLS::WindowSet, FBNLS::WindowUnnamed,
|
|
|
|
"Unnamed");
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-11-14 00:23:19 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
};
|
2003-02-18 15:11:12 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
/// holds slit client info
|
|
|
|
class SlitClient {
|
|
|
|
public:
|
|
|
|
/// For adding an actual window
|
|
|
|
SlitClient(BScreen *screen, Window win) {
|
|
|
|
initialize(screen, win);
|
|
|
|
}
|
|
|
|
/// For adding a placeholder
|
|
|
|
explicit SlitClient(const char *name) {
|
|
|
|
initialize();
|
|
|
|
match_name = (name == 0 ? "" : name);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now we pre-initialize a list of slit clients with names for
|
|
|
|
// comparison with incoming client windows. This allows the slit
|
|
|
|
// to maintain a sorted order based on a saved window name list.
|
|
|
|
// Incoming windows not found in the list are appended. Matching
|
|
|
|
// duplicates are inserted after the last found instance of the
|
|
|
|
// matching name.
|
|
|
|
std::string match_name;
|
|
|
|
|
|
|
|
Window window, client_window, icon_window;
|
|
|
|
|
|
|
|
int x, y;
|
|
|
|
unsigned int width, height;
|
|
|
|
bool visible; ///< wheter the client should be visible or not
|
|
|
|
|
|
|
|
void initialize(BScreen *screen = 0, Window win= None) {
|
|
|
|
client_window = win;
|
|
|
|
window = icon_window = None;
|
|
|
|
x = y = 0;
|
|
|
|
width = height = 0;
|
|
|
|
if (match_name.size() == 0)
|
|
|
|
getWMName(screen, client_window, match_name);
|
|
|
|
visible = true;
|
|
|
|
}
|
|
|
|
void disableEvents() {
|
2003-02-20 16:41:22 +00:00
|
|
|
if (window == 0)
|
|
|
|
return;
|
2003-01-12 17:56:15 +00:00
|
|
|
Display *disp = FbTk::App::instance()->display();
|
|
|
|
XSelectInput(disp, window, NoEventMask);
|
|
|
|
}
|
|
|
|
void enableEvents() {
|
2003-02-20 16:41:22 +00:00
|
|
|
if (window == 0)
|
|
|
|
return;
|
2003-01-12 17:56:15 +00:00
|
|
|
Display *disp = FbTk::App::instance()->display();
|
|
|
|
XSelectInput(disp, window, StructureNotifyMask |
|
|
|
|
SubstructureNotifyMask | EnterWindowMask);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
class SlitClientMenuItem: public FbTk::MenuItem {
|
|
|
|
public:
|
|
|
|
explicit SlitClientMenuItem(SlitClient &client, FbTk::RefCount<FbTk::Command> &cmd):
|
|
|
|
FbTk::MenuItem(client.match_name.c_str(), cmd), m_client(client) {
|
|
|
|
FbTk::MenuItem::setSelected(client.visible);
|
|
|
|
}
|
|
|
|
const std::string &label() const {
|
|
|
|
return m_client.match_name;
|
|
|
|
}
|
|
|
|
bool isSelected() const {
|
|
|
|
return m_client.visible;
|
|
|
|
}
|
|
|
|
void click(int button, int time) {
|
|
|
|
m_client.visible = !m_client.visible;
|
|
|
|
FbTk::MenuItem::click(button, time);
|
2003-02-23 00:54:13 +00:00
|
|
|
Fluxbox::instance()->save_rc();
|
2003-01-12 17:56:15 +00:00
|
|
|
}
|
|
|
|
private:
|
|
|
|
SlitClient &m_client;
|
|
|
|
};
|
|
|
|
|
|
|
|
class SlitDirMenuItem: public FbTk::MenuItem {
|
|
|
|
public:
|
2003-04-16 16:18:06 +00:00
|
|
|
SlitDirMenuItem(const char *label, Slit &slit, FbTk::RefCount<FbTk::Command> &cmd)
|
|
|
|
:FbTk::MenuItem(label,cmd),
|
|
|
|
m_slit(slit),
|
|
|
|
m_label(label ? label : "") {
|
2003-01-12 17:56:15 +00:00
|
|
|
setLabel(m_label.c_str()); // update label
|
|
|
|
}
|
|
|
|
void click(int button, int time) {
|
|
|
|
// toggle direction
|
|
|
|
if (m_slit.direction() == Slit::HORIZONTAL)
|
|
|
|
m_slit.setDirection(Slit::VERTICAL);
|
|
|
|
else
|
|
|
|
m_slit.setDirection(Slit::HORIZONTAL);
|
|
|
|
setLabel(m_label.c_str());
|
2003-04-16 16:18:06 +00:00
|
|
|
FbTk::MenuItem::click(button, time);
|
2003-01-12 17:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void setLabel(const char *label) {
|
|
|
|
I18n *i18n = I18n::instance();
|
|
|
|
m_label = (label ? label : "");
|
|
|
|
std::string reallabel = m_label + " " +
|
|
|
|
( m_slit.direction() == Slit::HORIZONTAL ?
|
|
|
|
i18n->getMessage(
|
|
|
|
FBNLS::CommonSet, FBNLS::CommonDirectionHoriz,
|
|
|
|
"Horizontal") :
|
|
|
|
i18n->getMessage(
|
|
|
|
FBNLS::CommonSet, FBNLS::CommonDirectionVert,
|
|
|
|
"Vertical") );
|
|
|
|
FbTk::MenuItem::setLabel(reallabel.c_str());
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
Slit &m_slit;
|
|
|
|
std::string m_label;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PlaceSlitMenuItem: public FbTk::MenuItem {
|
|
|
|
public:
|
2003-04-16 16:18:06 +00:00
|
|
|
PlaceSlitMenuItem(const char *label, Slit &slit, Slit::Placement place, FbTk::RefCount<FbTk::Command> &cmd):
|
|
|
|
FbTk::MenuItem(label, cmd), m_slit(slit), m_place(place) {
|
2003-01-12 17:56:15 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
bool isEnabled() const { return m_slit.placement() != m_place; }
|
|
|
|
void click(int button, int time) {
|
|
|
|
m_slit.setPlacement(m_place);
|
2003-04-16 16:18:06 +00:00
|
|
|
FbTk::MenuItem::click(button, time);
|
2003-01-12 17:56:15 +00:00
|
|
|
}
|
|
|
|
private:
|
|
|
|
Slit &m_slit;
|
|
|
|
Slit::Placement m_place;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
}; // End anonymous namespace
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 10:46:07 +00:00
|
|
|
class SlitTheme:public FbTk::Theme {
|
|
|
|
public:
|
2003-05-15 12:00:46 +00:00
|
|
|
explicit SlitTheme(Slit &slit):FbTk::Theme(slit.screen().screenNumber()),
|
2003-04-25 10:46:07 +00:00
|
|
|
m_slit(slit),
|
2003-05-04 20:50:15 +00:00
|
|
|
m_texture(*this, "slit", "Slit") {
|
|
|
|
// default texture type
|
|
|
|
m_texture->setType(FbTk::Texture::SOLID);
|
|
|
|
}
|
2003-04-25 10:46:07 +00:00
|
|
|
void reconfigTheme() {
|
|
|
|
m_slit.reconfigure();
|
|
|
|
}
|
|
|
|
const FbTk::Texture &texture() const { return *m_texture; }
|
|
|
|
private:
|
|
|
|
Slit &m_slit;
|
|
|
|
FbTk::ThemeItem<FbTk::Texture> m_texture;
|
|
|
|
};
|
|
|
|
|
2003-02-18 15:11:12 +00:00
|
|
|
Slit::Slit(BScreen &scr, FbTk::XLayer &layer, const char *filename)
|
2003-05-11 17:42:51 +00:00
|
|
|
: m_screen(scr), m_timer(this),
|
|
|
|
m_slitmenu(*scr.menuTheme(),
|
2003-05-15 12:00:46 +00:00
|
|
|
scr.screenNumber(),
|
2003-05-11 17:42:51 +00:00
|
|
|
*scr.getImageControl(),
|
|
|
|
*scr.layerManager().getLayer(Fluxbox::instance()->getMenuLayer())),
|
|
|
|
m_placement_menu(*scr.menuTheme(),
|
2003-05-15 12:00:46 +00:00
|
|
|
scr.screenNumber(),
|
2003-05-11 17:42:51 +00:00
|
|
|
*scr.getImageControl(),
|
|
|
|
*scr.layerManager().getLayer(Fluxbox::instance()->getMenuLayer())),
|
|
|
|
m_clientlist_menu(*scr.menuTheme(),
|
2003-05-15 12:00:46 +00:00
|
|
|
scr.screenNumber(),
|
2003-05-11 17:42:51 +00:00
|
|
|
*scr.getImageControl(),
|
|
|
|
*scr.layerManager().getLayer(Fluxbox::instance()->getMenuLayer())),
|
|
|
|
m_layermenu(new LayerMenu<Slit>(*scr.menuTheme(),
|
2003-05-15 12:00:46 +00:00
|
|
|
scr.screenNumber(),
|
2003-04-25 17:27:36 +00:00
|
|
|
*scr.getImageControl(),
|
|
|
|
*scr.layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
|
2003-05-11 17:42:51 +00:00
|
|
|
this,
|
|
|
|
true)),
|
|
|
|
//For KDE dock applets
|
|
|
|
m_kwm1_dockwindow(XInternAtom(FbTk::App::instance()->display(),
|
|
|
|
"KWM_DOCKWINDOW", False)), //KDE v1.x
|
|
|
|
m_kwm2_dockwindow(XInternAtom(FbTk::App::instance()->display(),
|
|
|
|
"_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False)), //KDE v2.x
|
|
|
|
|
2003-04-25 10:46:07 +00:00
|
|
|
m_layeritem(0),
|
|
|
|
m_slit_theme(new SlitTheme(*this)) {
|
2003-02-18 15:11:12 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
// default placement and direction
|
2003-04-16 16:18:06 +00:00
|
|
|
m_direction = screen().getSlitDirection();
|
|
|
|
m_placement = screen().getSlitPlacement();
|
2003-05-11 17:42:51 +00:00
|
|
|
m_hidden = m_do_auto_hide = screen().doSlitAutoHide();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
frame.pixmap = None;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
m_timer.setTimeout(200); // default timeout
|
|
|
|
m_timer.fireOnce(true);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
XSetWindowAttributes attrib;
|
|
|
|
unsigned long create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel |
|
|
|
|
CWColormap | CWOverrideRedirect | CWEventMask;
|
|
|
|
attrib.background_pixmap = None;
|
|
|
|
attrib.background_pixel = attrib.border_pixel =
|
2003-04-25 10:46:07 +00:00
|
|
|
screen().rootTheme().borderColor().pixel();
|
2003-05-10 22:59:32 +00:00
|
|
|
attrib.colormap = screen().rootWindow().colormap();
|
2002-12-01 13:42:15 +00:00
|
|
|
attrib.override_redirect = True;
|
|
|
|
attrib.event_mask = SubstructureRedirectMask | ButtonPressMask |
|
2003-05-13 13:28:28 +00:00
|
|
|
EnterWindowMask | LeaveWindowMask | ExposureMask;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
frame.x = frame.y = 0;
|
|
|
|
frame.width = frame.height = 1;
|
2003-01-12 17:56:15 +00:00
|
|
|
Display *disp = FbTk::App::instance()->display();
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.window =
|
2003-05-10 22:59:32 +00:00
|
|
|
XCreateWindow(disp, screen().rootWindow().window(), frame.x, frame.y,
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.width, frame.height, screen().rootTheme().borderWidth(),
|
2003-05-10 22:59:32 +00:00
|
|
|
screen().rootWindow().depth(), InputOutput, screen().rootWindow().visual(),
|
2002-12-01 13:42:15 +00:00
|
|
|
create_mask, &attrib);
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
FbTk::EventManager::instance()->add(*this, frame.window);
|
2003-05-13 21:12:18 +00:00
|
|
|
m_transp.reset(new FbTk::Transparent(screen().rootPixmap(), frame.window.drawable(),
|
|
|
|
*screen().slitAlphaResource(),
|
2003-05-15 12:00:46 +00:00
|
|
|
screen().screenNumber()));
|
2003-02-20 16:41:22 +00:00
|
|
|
|
|
|
|
m_layeritem.reset(new FbTk::XLayerItem(frame.window, layer));
|
2003-01-12 17:56:15 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
// Get client list for sorting purposes
|
2003-01-12 17:56:15 +00:00
|
|
|
loadClientList(filename);
|
|
|
|
|
|
|
|
setupMenu();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
reconfigure();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Slit::~Slit() {
|
2003-01-12 17:56:15 +00:00
|
|
|
if (frame.pixmap != 0)
|
2003-02-20 16:41:22 +00:00
|
|
|
screen().getImageControl()->removeImage(frame.pixmap);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Slit::addClient(Window w) {
|
2003-01-12 17:56:15 +00:00
|
|
|
#ifdef DEBUG
|
2003-02-20 16:41:22 +00:00
|
|
|
cerr<<__FILE__": addClient(w = 0x"<<hex<<w<<dec<<")"<<endl;
|
2003-01-12 17:56:15 +00:00
|
|
|
#endif // DEBUG
|
2003-05-11 17:42:51 +00:00
|
|
|
// Can't add non existent window
|
2002-12-01 13:42:15 +00:00
|
|
|
if (w == None)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Look for slot in client list by name
|
|
|
|
SlitClient *client = 0;
|
|
|
|
std::string match_name;
|
2003-02-20 16:41:22 +00:00
|
|
|
::getWMName(&screen(), w, match_name);
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClients::iterator it = m_client_list.begin();
|
|
|
|
SlitClients::iterator it_end = m_client_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
bool found_match = false;
|
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
// If the name matches...
|
|
|
|
if ((*it)->match_name == match_name) {
|
|
|
|
// Use the slot if no window is assigned
|
|
|
|
if ((*it)->window == None) {
|
|
|
|
client = (*it);
|
2003-02-20 16:41:22 +00:00
|
|
|
client->initialize(&screen(), w);
|
2002-12-01 13:42:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Otherwise keep looking for an unused match or a non-match
|
|
|
|
found_match = true; // Possibly redundant
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
} else if (found_match) {
|
|
|
|
// Insert before first non-match after a previously found match?
|
2003-02-20 16:41:22 +00:00
|
|
|
client = new SlitClient(&screen(), w);
|
2003-05-11 17:42:51 +00:00
|
|
|
m_client_list.insert(it, client);
|
2002-12-01 13:42:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Append to client list?
|
|
|
|
if (client == 0) {
|
2003-02-20 16:41:22 +00:00
|
|
|
client = new SlitClient(&screen(), w);
|
2003-05-11 17:42:51 +00:00
|
|
|
m_client_list.push_back(client);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2003-01-12 17:56:15 +00:00
|
|
|
|
|
|
|
Display *disp = FbTk::App::instance()->display();
|
2002-12-01 13:42:15 +00:00
|
|
|
XWMHints *wmhints = XGetWMHints(disp, w);
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
if (wmhints != 0) {
|
2002-12-01 13:42:15 +00:00
|
|
|
if ((wmhints->flags & IconWindowHint) &&
|
|
|
|
(wmhints->icon_window != None)) {
|
2003-05-15 12:00:46 +00:00
|
|
|
XMoveWindow(disp, client->client_window, screen().width() + 10,
|
|
|
|
screen().height() + 10);
|
2002-12-01 13:42:15 +00:00
|
|
|
XMapWindow(disp, client->client_window);
|
|
|
|
client->icon_window = wmhints->icon_window;
|
|
|
|
client->window = client->icon_window;
|
|
|
|
} else {
|
|
|
|
client->icon_window = None;
|
|
|
|
client->window = client->client_window;
|
|
|
|
}
|
|
|
|
|
|
|
|
XFree(wmhints);
|
|
|
|
} else {
|
|
|
|
client->icon_window = None;
|
|
|
|
client->window = client->client_window;
|
|
|
|
}
|
2003-01-12 17:56:15 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
XWindowAttributes attrib;
|
2003-01-12 17:56:15 +00:00
|
|
|
|
2002-11-14 00:23:19 +00:00
|
|
|
#ifdef KDE
|
2003-01-12 17:56:15 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
//Check and see if new client is a KDE dock applet
|
|
|
|
//If so force reasonable size
|
2003-02-20 16:41:22 +00:00
|
|
|
bool iskdedockapp = false;
|
2002-12-01 13:42:15 +00:00
|
|
|
Atom ajunk;
|
|
|
|
int ijunk;
|
2003-02-20 16:41:22 +00:00
|
|
|
unsigned long *data = 0, uljunk;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
// Check if KDE v2.x dock applet
|
|
|
|
if (XGetWindowProperty(disp, w,
|
2003-05-11 17:42:51 +00:00
|
|
|
m_kwm2_dockwindow, 0l, 1l, False,
|
|
|
|
m_kwm2_dockwindow,
|
2002-12-01 13:42:15 +00:00
|
|
|
&ajunk, &ijunk, &uljunk, &uljunk,
|
|
|
|
(unsigned char **) &data) == Success) {
|
|
|
|
iskdedockapp = (data && data[0] != 0);
|
|
|
|
XFree((char *) data);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if KDE v1.x dock applet
|
|
|
|
if (!iskdedockapp) {
|
|
|
|
if (XGetWindowProperty(disp, w,
|
2003-05-11 17:42:51 +00:00
|
|
|
m_kwm1_dockwindow, 0l, 1l, False,
|
|
|
|
m_kwm1_dockwindow,
|
2002-12-01 13:42:15 +00:00
|
|
|
&ajunk, &ijunk, &uljunk, &uljunk,
|
|
|
|
(unsigned char **) &data) == Success) {
|
|
|
|
iskdedockapp = (data && data[0] != 0);
|
|
|
|
XFree((char *) data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iskdedockapp)
|
|
|
|
client->width = client->height = 24;
|
|
|
|
else
|
2002-11-14 00:23:19 +00:00
|
|
|
#endif // KDE
|
2003-01-12 17:56:15 +00:00
|
|
|
|
|
|
|
{
|
2002-12-01 13:42:15 +00:00
|
|
|
if (XGetWindowAttributes(disp, client->window, &attrib)) {
|
|
|
|
client->width = attrib.width;
|
|
|
|
client->height = attrib.height;
|
2003-01-12 17:56:15 +00:00
|
|
|
} else { // set default size if we failed to get window attributes
|
2002-12-01 13:42:15 +00:00
|
|
|
client->width = client->height = 64;
|
|
|
|
}
|
2003-01-12 17:56:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
// disable border for client window
|
2002-12-01 13:42:15 +00:00
|
|
|
XSetWindowBorderWidth(disp, client->window, 0);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
// disable events to frame.window
|
|
|
|
frame.window.setEventMask(NoEventMask);
|
|
|
|
client->disableEvents();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
XReparentWindow(disp, client->window, frame.window.window(), 0, 0);
|
2002-12-01 13:42:15 +00:00
|
|
|
XMapRaised(disp, client->window);
|
|
|
|
XChangeSaveSet(disp, client->window, SetModeInsert);
|
2003-02-20 16:41:22 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
// reactivate events for frame.window
|
|
|
|
frame.window.setEventMask(SubstructureRedirectMask |
|
2003-05-13 13:28:28 +00:00
|
|
|
ButtonPressMask | EnterWindowMask | LeaveWindowMask | ExposureMask);
|
2003-02-20 16:41:22 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
// setup event for slit client window
|
|
|
|
client->enableEvents();
|
|
|
|
// flush events
|
2002-12-01 13:42:15 +00:00
|
|
|
XFlush(disp);
|
2003-02-20 16:41:22 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
// add slit client to eventmanager
|
|
|
|
FbTk::EventManager::instance()->add(*this, client->client_window);
|
|
|
|
FbTk::EventManager::instance()->add(*this, client->icon_window);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
frame.window.show();
|
2003-05-13 21:12:18 +00:00
|
|
|
clearWindow();
|
2002-12-01 13:42:15 +00:00
|
|
|
reconfigure();
|
2002-05-29 06:21:59 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
updateClientmenu();
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
saveClientList();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
void Slit::setDirection(Direction dir) {
|
|
|
|
m_direction = dir;
|
2003-04-16 16:18:06 +00:00
|
|
|
screen().saveSlitDirection(dir);
|
2003-01-12 17:56:15 +00:00
|
|
|
reconfigure();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Slit::setPlacement(Placement place) {
|
|
|
|
m_placement = place;
|
2003-04-16 16:18:06 +00:00
|
|
|
screen().saveSlitPlacement(place);
|
2003-01-12 17:56:15 +00:00
|
|
|
reconfigure();
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
void Slit::removeClient(SlitClient *client, bool remap, bool destroy) {
|
2003-01-12 17:56:15 +00:00
|
|
|
#ifdef DEBUG
|
2003-02-20 16:41:22 +00:00
|
|
|
cerr<<"Slit::removeClient( client->client_window = 0x"<<hex<<client->client_window<<
|
|
|
|
", client->icon_window)"<<endl;
|
2003-01-12 17:56:15 +00:00
|
|
|
#endif // DEBUG
|
|
|
|
// remove from event manager
|
2003-02-20 16:41:22 +00:00
|
|
|
if (client->client_window != 0)
|
|
|
|
FbTk::EventManager::instance()->remove(client->client_window);
|
|
|
|
if (client->icon_window != 0)
|
|
|
|
FbTk::EventManager::instance()->remove(client->icon_window);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
// Destructive removal?
|
|
|
|
if (destroy)
|
2003-05-11 17:42:51 +00:00
|
|
|
m_client_list.remove(client);
|
2002-12-01 13:42:15 +00:00
|
|
|
else // Clear the window info, but keep around to help future sorting?
|
|
|
|
client->initialize();
|
|
|
|
|
2003-02-20 16:41:22 +00:00
|
|
|
screen().removeNetizen(client->window);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-02-20 16:41:22 +00:00
|
|
|
if (remap && client->window != 0) {
|
2003-01-12 17:56:15 +00:00
|
|
|
Display *disp = FbTk::App::instance()->display();
|
2003-02-20 16:41:22 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
if (!client->visible)
|
|
|
|
XMapWindow(disp, client->window);
|
2003-02-20 16:41:22 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
client->disableEvents();
|
|
|
|
// stop events to frame.window temporarly
|
|
|
|
frame.window.setEventMask(NoEventMask);
|
2003-05-10 22:59:32 +00:00
|
|
|
XReparentWindow(disp, client->window, screen().rootWindow().window(),
|
2002-02-04 22:33:09 +00:00
|
|
|
client->x, client->y);
|
2002-12-01 13:42:15 +00:00
|
|
|
XChangeSaveSet(disp, client->window, SetModeDelete);
|
2003-01-12 17:56:15 +00:00
|
|
|
// reactivate events to frame.window
|
|
|
|
frame.window.setEventMask(SubstructureRedirectMask | ButtonPressMask |
|
2003-05-13 13:28:28 +00:00
|
|
|
EnterWindowMask | LeaveWindowMask | ExposureMask);
|
2002-12-01 13:42:15 +00:00
|
|
|
XFlush(disp);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Destructive removal?
|
|
|
|
if (destroy)
|
|
|
|
delete client;
|
2003-02-17 12:53:21 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
updateClientmenu();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-02-04 22:33:09 +00:00
|
|
|
void Slit::removeClient(Window w, bool remap) {
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
bool reconf = false;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClients::iterator it = m_client_list.begin();
|
|
|
|
SlitClients::iterator it_end = m_client_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
if ((*it)->window == w) {
|
|
|
|
removeClient((*it), remap, false);
|
|
|
|
reconf = true;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (reconf)
|
|
|
|
reconfigure();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-14 00:23:19 +00:00
|
|
|
void Slit::reconfigure() {
|
2003-05-13 21:12:18 +00:00
|
|
|
m_transp->setAlpha(*screen().slitAlphaResource());
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.width = 0;
|
|
|
|
frame.height = 0;
|
|
|
|
|
2003-04-16 16:18:06 +00:00
|
|
|
// be sure to sync slit auto hide up with the screen's menu resource
|
2003-05-11 17:42:51 +00:00
|
|
|
m_do_auto_hide = screen().doSlitAutoHide();
|
2003-04-16 16:18:06 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
// Need to count windows because not all client list entries
|
|
|
|
// actually correspond to mapped windows.
|
|
|
|
int num_windows = 0;
|
2003-04-25 10:46:07 +00:00
|
|
|
const int bevel_width = screen().rootTheme().bevelWidth();
|
2003-01-12 17:56:15 +00:00
|
|
|
switch (direction()) {
|
2003-05-04 20:50:15 +00:00
|
|
|
case VERTICAL: {
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClients::iterator it = m_client_list.begin();
|
|
|
|
SlitClients::iterator it_end = m_client_list.end();
|
2003-05-04 20:50:15 +00:00
|
|
|
for (; it != it_end; ++it) {
|
2003-05-11 17:42:51 +00:00
|
|
|
// client created window?
|
2003-05-04 20:50:15 +00:00
|
|
|
if ((*it)->window != None && (*it)->visible) {
|
|
|
|
num_windows++;
|
2003-05-11 17:42:51 +00:00
|
|
|
frame.height += (*it)->height + bevel_width;
|
|
|
|
|
2003-05-04 20:50:15 +00:00
|
|
|
if (frame.width < (*it)->width)
|
|
|
|
frame.width = (*it)->width;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
}
|
2003-05-04 20:50:15 +00:00
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
if (frame.width < 1)
|
|
|
|
frame.width = 1;
|
|
|
|
else
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.width += (bevel_width * 2);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
if (frame.height < 1)
|
|
|
|
frame.height = 1;
|
|
|
|
else
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.height += bevel_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-05-04 20:50:15 +00:00
|
|
|
case HORIZONTAL: {
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClients::iterator it = m_client_list.begin();
|
|
|
|
SlitClients::iterator it_end = m_client_list.end();
|
2003-05-04 20:50:15 +00:00
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
//client created window?
|
|
|
|
if ((*it)->window != None && (*it)->visible) {
|
|
|
|
num_windows++;
|
|
|
|
frame.width += (*it)->width + bevel_width;
|
|
|
|
//frame height < client height?
|
|
|
|
if (frame.height < (*it)->height)
|
|
|
|
frame.height = (*it)->height;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
}
|
2003-05-04 20:50:15 +00:00
|
|
|
break;
|
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
if (frame.width < 1)
|
|
|
|
frame.width = 1;
|
|
|
|
else
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.width += bevel_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
if (frame.height < 1)
|
|
|
|
frame.height = 1;
|
|
|
|
else
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.height += bevel_width*2;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
reposition();
|
2003-01-12 17:56:15 +00:00
|
|
|
Display *disp = FbTk::App::instance()->display();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.window.setBorderWidth(screen().rootTheme().borderWidth());
|
|
|
|
frame.window.setBorderColor(screen().rootTheme().borderColor());
|
2003-05-11 17:42:51 +00:00
|
|
|
// did we actually use slit slots
|
2002-12-01 13:42:15 +00:00
|
|
|
if (num_windows == 0)
|
2003-01-12 17:56:15 +00:00
|
|
|
frame.window.hide();
|
2002-12-01 13:42:15 +00:00
|
|
|
else
|
2003-01-12 17:56:15 +00:00
|
|
|
frame.window.show();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
Pixmap tmp = frame.pixmap;
|
2003-02-20 16:41:22 +00:00
|
|
|
FbTk::ImageControl *image_ctrl = screen().getImageControl();
|
2003-04-25 10:46:07 +00:00
|
|
|
const FbTk::Texture &texture = m_slit_theme->texture();
|
2003-05-13 13:28:28 +00:00
|
|
|
if (texture.type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID) &&
|
|
|
|
texture.pixmap().drawable() == 0) {
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.pixmap = None;
|
2003-01-12 17:56:15 +00:00
|
|
|
frame.window.setBackgroundColor(texture.color());
|
2002-12-01 13:42:15 +00:00
|
|
|
} else {
|
|
|
|
frame.pixmap = image_ctrl->renderImage(frame.width, frame.height,
|
|
|
|
texture);
|
2003-05-13 13:28:28 +00:00
|
|
|
if (frame.pixmap == 0)
|
|
|
|
frame.window.setBackgroundColor(texture.color());
|
|
|
|
else
|
|
|
|
frame.window.setBackgroundPixmap(frame.pixmap);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tmp)
|
|
|
|
image_ctrl->removeImage(tmp);
|
2003-01-12 17:56:15 +00:00
|
|
|
|
2003-05-13 21:12:18 +00:00
|
|
|
clearWindow();
|
2002-12-01 13:42:15 +00:00
|
|
|
int x, y;
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
switch (direction()) {
|
2002-12-01 13:42:15 +00:00
|
|
|
case VERTICAL:
|
|
|
|
x = 0;
|
2003-04-25 10:46:07 +00:00
|
|
|
y = bevel_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
{
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClients::iterator it = m_client_list.begin();
|
|
|
|
SlitClients::iterator it_end = m_client_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
if ((*it)->window == None)
|
|
|
|
continue;
|
2002-05-29 06:21:59 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
//client created window?
|
|
|
|
if ((*it)->visible)
|
|
|
|
XMapWindow(disp, (*it)->window);
|
|
|
|
else {
|
|
|
|
(*it)->disableEvents();
|
|
|
|
XUnmapWindow(disp, (*it)->window);
|
|
|
|
(*it)->enableEvents();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
x = (frame.width - (*it)->width) / 2;
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
XMoveResizeWindow(disp, (*it)->window, x, y,
|
|
|
|
(*it)->width, (*it)->height);
|
2002-02-04 22:33:09 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
// for ICCCM compliance
|
2002-12-01 13:42:15 +00:00
|
|
|
(*it)->x = x;
|
|
|
|
(*it)->y = y;
|
|
|
|
|
|
|
|
XEvent event;
|
|
|
|
event.type = ConfigureNotify;
|
|
|
|
|
|
|
|
event.xconfigure.display = disp;
|
|
|
|
event.xconfigure.event = (*it)->window;
|
|
|
|
event.xconfigure.window = (*it)->window;
|
|
|
|
event.xconfigure.x = x;
|
|
|
|
event.xconfigure.y = y;
|
|
|
|
event.xconfigure.width = (*it)->width;
|
|
|
|
event.xconfigure.height = (*it)->height;
|
|
|
|
event.xconfigure.border_width = 0;
|
2003-01-12 17:56:15 +00:00
|
|
|
event.xconfigure.above = frame.window.window();
|
2002-12-01 13:42:15 +00:00
|
|
|
event.xconfigure.override_redirect = False;
|
|
|
|
|
|
|
|
XSendEvent(disp, (*it)->window, False, StructureNotifyMask,
|
|
|
|
&event);
|
|
|
|
|
2003-04-25 10:46:07 +00:00
|
|
|
y += (*it)->height + bevel_width;
|
|
|
|
} // end for
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HORIZONTAL:
|
2003-04-25 10:46:07 +00:00
|
|
|
x = bevel_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
y = 0;
|
|
|
|
|
|
|
|
{
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClients::iterator it = m_client_list.begin();
|
|
|
|
SlitClients::iterator it_end = m_client_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
for (; it != it_end; ++it) {
|
2003-01-12 17:56:15 +00:00
|
|
|
//client created window?
|
2002-12-01 13:42:15 +00:00
|
|
|
if ((*it)->window == None)
|
|
|
|
continue;
|
2002-05-29 06:21:59 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
if ((*it)->visible) {
|
|
|
|
XMapWindow(disp, (*it)->window);
|
|
|
|
} else {
|
|
|
|
(*it)->disableEvents();
|
|
|
|
XUnmapWindow(disp, (*it)->window);
|
|
|
|
(*it)->enableEvents();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
y = (frame.height - (*it)->height) / 2;
|
2002-02-04 22:33:09 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
XMoveResizeWindow(disp, (*it)->window, x, y,
|
|
|
|
(*it)->width, (*it)->height);
|
2002-02-04 22:33:09 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// for ICCCM compliance
|
2002-12-01 13:42:15 +00:00
|
|
|
(*it)->x = x;
|
|
|
|
(*it)->y = y;
|
|
|
|
|
|
|
|
XEvent event;
|
|
|
|
event.type = ConfigureNotify;
|
|
|
|
|
|
|
|
event.xconfigure.display = disp;
|
|
|
|
event.xconfigure.event = (*it)->window;
|
|
|
|
event.xconfigure.window = (*it)->window;
|
2003-04-25 10:46:07 +00:00
|
|
|
event.xconfigure.x = frame.x + x + screen().rootTheme().borderWidth();
|
|
|
|
event.xconfigure.y = frame.y + y + screen().rootTheme().borderWidth();
|
2002-12-01 13:42:15 +00:00
|
|
|
event.xconfigure.width = (*it)->width;
|
|
|
|
event.xconfigure.height = (*it)->height;
|
|
|
|
event.xconfigure.border_width = 0;
|
2003-01-12 17:56:15 +00:00
|
|
|
event.xconfigure.above = frame.window.window();
|
2002-12-01 13:42:15 +00:00
|
|
|
event.xconfigure.override_redirect = False;
|
|
|
|
|
|
|
|
XSendEvent(disp, (*it)->window, False, StructureNotifyMask,
|
|
|
|
&event);
|
|
|
|
|
2003-04-25 10:46:07 +00:00
|
|
|
x += (*it)->width + bevel_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
if (doAutoHide() && !isHidden() && !m_timer.isTiming())
|
|
|
|
m_timer.start();
|
2003-05-01 15:03:36 +00:00
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
m_slitmenu.reconfigure();
|
2003-01-12 17:56:15 +00:00
|
|
|
updateClientmenu();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 21:51:07 +00:00
|
|
|
void Slit::reposition() {
|
2002-12-01 13:42:15 +00:00
|
|
|
int head_x = 0,
|
|
|
|
head_y = 0,
|
|
|
|
head_w,
|
|
|
|
head_h;
|
2003-01-12 17:56:15 +00:00
|
|
|
|
2003-05-15 12:00:46 +00:00
|
|
|
head_w = screen().width();
|
|
|
|
head_h = screen().height();
|
2003-04-25 10:46:07 +00:00
|
|
|
int border_width = screen().rootTheme().borderWidth();
|
|
|
|
int bevel_width = screen().rootTheme().bevelWidth();
|
2002-03-19 14:30:43 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
// place the slit in the appropriate place
|
2003-01-12 17:56:15 +00:00
|
|
|
switch (placement()) {
|
2002-12-01 13:42:15 +00:00
|
|
|
case TOPLEFT:
|
|
|
|
frame.x = head_x;
|
|
|
|
frame.y = head_y;
|
2003-01-12 17:56:15 +00:00
|
|
|
if (direction() == VERTICAL) {
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.x_hidden = bevel_width -
|
|
|
|
border_width - frame.width;
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.y_hidden = head_y;
|
|
|
|
} else {
|
|
|
|
frame.x_hidden = head_x;
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.y_hidden = bevel_width -
|
|
|
|
border_width - frame.height;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CENTERLEFT:
|
|
|
|
frame.x = head_x;
|
|
|
|
frame.y = head_y + (head_h - frame.height) / 2;
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.x_hidden = head_x + bevel_width -
|
|
|
|
border_width - frame.width;
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.y_hidden = frame.y;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BOTTOMLEFT:
|
|
|
|
frame.x = head_x;
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.y = head_h - frame.height - border_width*2;
|
2003-01-12 17:56:15 +00:00
|
|
|
if (direction() == VERTICAL) {
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.x_hidden = head_x + bevel_width -
|
|
|
|
border_width - frame.width;
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.y_hidden = frame.y;
|
|
|
|
} else {
|
|
|
|
frame.x_hidden = head_x;
|
|
|
|
frame.y_hidden = head_y + head_h -
|
2003-04-25 10:46:07 +00:00
|
|
|
bevel_width - border_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TOPCENTER:
|
|
|
|
frame.x = head_x + ((head_w - frame.width) / 2);
|
|
|
|
frame.y = head_y;
|
|
|
|
frame.x_hidden = frame.x;
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.y_hidden = head_y + bevel_width -
|
|
|
|
border_width - frame.height;
|
2002-12-01 13:42:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BOTTOMCENTER:
|
|
|
|
frame.x = head_x + ((head_w - frame.width) / 2);
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.y = head_y + head_h - frame.height - border_width*2;
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.x_hidden = frame.x;
|
|
|
|
frame.y_hidden = head_y + head_h -
|
2003-04-25 10:46:07 +00:00
|
|
|
bevel_width - border_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case TOPRIGHT:
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.x = head_x + head_w - frame.width - border_width*2;
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.y = head_y;
|
2003-01-12 17:56:15 +00:00
|
|
|
if (direction() == VERTICAL) {
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.x_hidden = head_x + head_w -
|
2003-04-25 10:46:07 +00:00
|
|
|
bevel_width - border_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.y_hidden = head_y;
|
|
|
|
} else {
|
|
|
|
frame.x_hidden = frame.x;
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.y_hidden = head_y + bevel_width -
|
|
|
|
border_width - frame.height;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CENTERRIGHT:
|
|
|
|
default:
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.x = head_x + head_w - frame.width - border_width*2;
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.y = head_y + ((head_h - frame.height) / 2);
|
|
|
|
frame.x_hidden = head_x + head_w -
|
2003-04-25 10:46:07 +00:00
|
|
|
bevel_width - border_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.y_hidden = frame.y;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BOTTOMRIGHT:
|
2003-04-25 10:46:07 +00:00
|
|
|
frame.x = head_x + head_w - frame.width - border_width*2;
|
|
|
|
frame.y = head_y + head_h - frame.height - border_width*2;
|
2003-01-12 17:56:15 +00:00
|
|
|
if (direction() == VERTICAL) {
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.x_hidden = head_x + head_w -
|
2003-04-25 10:46:07 +00:00
|
|
|
bevel_width - border_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
frame.y_hidden = frame.y;
|
|
|
|
} else {
|
|
|
|
frame.x_hidden = frame.x;
|
|
|
|
frame.y_hidden = head_y + head_h -
|
2003-04-25 10:46:07 +00:00
|
|
|
bevel_width - border_width;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
if (isHidden()) {
|
2003-05-13 13:28:28 +00:00
|
|
|
frame.window.moveResize(frame.x_hidden, frame.y_hidden,
|
|
|
|
frame.width, frame.height);
|
2002-12-01 13:42:15 +00:00
|
|
|
} else {
|
2003-05-13 13:28:28 +00:00
|
|
|
frame.window.moveResize(frame.x, frame.y,
|
|
|
|
frame.width, frame.height);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 21:51:07 +00:00
|
|
|
void Slit::shutdown() {
|
2002-12-01 13:42:15 +00:00
|
|
|
saveClientList();
|
2003-05-11 17:42:51 +00:00
|
|
|
while (!m_client_list.empty())
|
|
|
|
removeClient(m_client_list.front(), true, true);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
void Slit::cycleClientsUp() {
|
2003-05-11 17:42:51 +00:00
|
|
|
if (m_client_list.size() < 2)
|
2003-01-12 23:52:37 +00:00
|
|
|
return;
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
// rotate client list up, ie the first goes last
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClients::iterator it = m_client_list.begin();
|
2003-01-12 17:56:15 +00:00
|
|
|
SlitClient *client = *it;
|
2003-05-11 17:42:51 +00:00
|
|
|
m_client_list.erase(it);
|
|
|
|
m_client_list.push_back(client);
|
2003-01-12 17:56:15 +00:00
|
|
|
reconfigure();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Slit::cycleClientsDown() {
|
2003-05-11 17:42:51 +00:00
|
|
|
if (m_client_list.size() < 2)
|
2003-01-12 23:52:37 +00:00
|
|
|
return;
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
// rotate client list down, ie the last goes first
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClient *client = m_client_list.back();
|
|
|
|
m_client_list.remove(client);
|
|
|
|
m_client_list.push_front(client);
|
2003-01-12 17:56:15 +00:00
|
|
|
reconfigure();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Slit::handleEvent(XEvent &event) {
|
2003-02-20 16:41:22 +00:00
|
|
|
if (event.type == ConfigureRequest) {
|
|
|
|
configureRequestEvent(event.xconfigurerequest);
|
|
|
|
} else if (event.type == DestroyNotify) {
|
2003-01-12 17:56:15 +00:00
|
|
|
removeClient(event.xdestroywindow.window, false);
|
|
|
|
} else if (event.type == UnmapNotify) {
|
|
|
|
removeClient(event.xany.window);
|
|
|
|
} else if (event.type == MapRequest) {
|
|
|
|
#ifdef KDE
|
|
|
|
//Check and see if client is KDE dock applet.
|
|
|
|
//If so add to Slit
|
|
|
|
bool iskdedockapp = false;
|
|
|
|
Atom ajunk;
|
|
|
|
int ijunk;
|
|
|
|
unsigned long *data = (unsigned long *) 0, uljunk;
|
|
|
|
Display *disp = FbTk::App::instance()->display();
|
|
|
|
// Check if KDE v2.x dock applet
|
|
|
|
if (XGetWindowProperty(disp, event.xmaprequest.window,
|
2003-05-11 19:01:09 +00:00
|
|
|
m_kwm2_dockwindow, 0l, 1l, False,
|
2003-01-12 17:56:15 +00:00
|
|
|
XA_WINDOW, &ajunk, &ijunk, &uljunk,
|
|
|
|
&uljunk, (unsigned char **) &data) == Success) {
|
|
|
|
|
|
|
|
if (data)
|
|
|
|
iskdedockapp = True;
|
|
|
|
XFree((char *) data);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if KDE v1.x dock applet
|
|
|
|
if (!iskdedockapp) {
|
|
|
|
if (XGetWindowProperty(disp, event.xmaprequest.window,
|
2003-05-11 19:01:09 +00:00
|
|
|
m_kwm1_dockwindow, 0l, 1l, False,
|
|
|
|
m_kwm1_dockwindow, &ajunk, &ijunk, &uljunk,
|
2003-01-12 17:56:15 +00:00
|
|
|
&uljunk, (unsigned char **) &data) == Success) {
|
|
|
|
iskdedockapp = (data && data[0] != 0);
|
|
|
|
XFree((char *) data);
|
|
|
|
}
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
if (iskdedockapp) {
|
|
|
|
XSelectInput(disp, event.xmaprequest.window, StructureNotifyMask);
|
|
|
|
addClient(event.xmaprequest.window);
|
|
|
|
}
|
|
|
|
#endif //KDE
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Slit::buttonPressEvent(XButtonEvent &e) {
|
|
|
|
if (e.window != frame.window.window())
|
2002-12-01 13:42:15 +00:00
|
|
|
return;
|
|
|
|
|
2003-02-18 15:11:12 +00:00
|
|
|
if (e.button == Button3) {
|
2003-05-11 17:42:51 +00:00
|
|
|
if (! m_slitmenu.isVisible()) {
|
|
|
|
int x = e.x_root - (m_slitmenu.width() / 2),
|
|
|
|
y = e.y_root - (m_slitmenu.height() / 2);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
if (x < 0)
|
|
|
|
x = 0;
|
2003-05-15 12:00:46 +00:00
|
|
|
else if (x + m_slitmenu.width() > screen().width())
|
|
|
|
x = screen().width() - m_slitmenu.width();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
if (y < 0)
|
|
|
|
y = 0;
|
2003-05-15 12:00:46 +00:00
|
|
|
else if (y + m_slitmenu.height() > screen().height())
|
|
|
|
y = screen().height() - m_slitmenu.height();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
m_slitmenu.move(x, y);
|
|
|
|
m_slitmenu.show();
|
2002-12-01 13:42:15 +00:00
|
|
|
} else
|
2003-05-11 17:42:51 +00:00
|
|
|
m_slitmenu.hide();
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
void Slit::enterNotifyEvent(XCrossingEvent &) {
|
2003-05-11 17:42:51 +00:00
|
|
|
if (! doAutoHide())
|
2002-12-01 13:42:15 +00:00
|
|
|
return;
|
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
if (isHidden()) {
|
|
|
|
if (! m_timer.isTiming())
|
|
|
|
m_timer.start();
|
2002-12-01 13:42:15 +00:00
|
|
|
} else {
|
2003-05-11 17:42:51 +00:00
|
|
|
if (m_timer.isTiming())
|
|
|
|
m_timer.stop();
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
void Slit::leaveNotifyEvent(XCrossingEvent &ev) {
|
2003-05-11 17:42:51 +00:00
|
|
|
if (! doAutoHide())
|
2002-12-01 13:42:15 +00:00
|
|
|
return;
|
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
if (isHidden()) {
|
|
|
|
if (m_timer.isTiming())
|
|
|
|
m_timer.stop();
|
2003-05-01 15:03:36 +00:00
|
|
|
} else {
|
2003-05-11 17:42:51 +00:00
|
|
|
if (! m_timer.isTiming()) {
|
2003-05-01 15:35:24 +00:00
|
|
|
// the menu is open, keep it firing until it closes
|
2003-05-11 17:42:51 +00:00
|
|
|
if (m_slitmenu.isVisible())
|
|
|
|
m_timer.fireOnce(false);
|
|
|
|
m_timer.start();
|
2003-05-01 15:35:24 +00:00
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
void Slit::configureRequestEvent(XConfigureRequestEvent &event) {
|
2002-12-01 13:42:15 +00:00
|
|
|
bool reconf = false;
|
|
|
|
XWindowChanges xwc;
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
xwc.x = event.x;
|
|
|
|
xwc.y = event.y;
|
|
|
|
xwc.width = event.width;
|
|
|
|
xwc.height = event.height;
|
2002-12-01 13:42:15 +00:00
|
|
|
xwc.border_width = 0;
|
2003-01-12 17:56:15 +00:00
|
|
|
xwc.sibling = event.above;
|
|
|
|
xwc.stack_mode = event.detail;
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
XConfigureWindow(FbTk::App::instance()->display(),
|
|
|
|
event.window, event.value_mask, &xwc);
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClients::iterator it = m_client_list.begin();
|
|
|
|
SlitClients::iterator it_end = m_client_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
for (; it != it_end; ++it) {
|
2003-01-12 17:56:15 +00:00
|
|
|
if ((*it)->window == event.window) {
|
|
|
|
if ((*it)->width != ((unsigned) event.width) ||
|
|
|
|
(*it)->height != ((unsigned) event.height)) {
|
|
|
|
(*it)->width = (unsigned) event.width;
|
|
|
|
(*it)->height = (unsigned) event.height;
|
2002-11-14 00:23:19 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
reconf = true; //requires reconfiguration
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (reconf)
|
|
|
|
reconfigure();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-05-13 13:28:28 +00:00
|
|
|
void Slit::exposeEvent(XExposeEvent &ev) {
|
2003-05-13 21:12:18 +00:00
|
|
|
clearWindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Slit::clearWindow() {
|
2003-05-07 22:53:21 +00:00
|
|
|
frame.window.clear();
|
2003-05-13 21:12:18 +00:00
|
|
|
if (frame.pixmap != 0) {
|
|
|
|
if (screen().rootPixmap() != m_transp->source())
|
2003-05-15 12:00:46 +00:00
|
|
|
m_transp->setSource(screen().rootPixmap(), screen().screenNumber());
|
2003-05-13 21:12:18 +00:00
|
|
|
|
|
|
|
m_transp->render(frame.window.x(), frame.window.y(),
|
|
|
|
0, 0,
|
|
|
|
frame.window.width(), frame.window.height());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-05-07 22:53:21 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-08-14 21:51:07 +00:00
|
|
|
void Slit::timeout() {
|
2003-05-11 17:42:51 +00:00
|
|
|
if (doAutoHide()) {
|
|
|
|
if (!m_slitmenu.isVisible()) {
|
|
|
|
m_timer.fireOnce(true);
|
2003-05-01 15:35:24 +00:00
|
|
|
} else
|
|
|
|
return;
|
2003-05-01 15:03:36 +00:00
|
|
|
} else
|
2003-05-11 17:42:51 +00:00
|
|
|
if (!isHidden()) return;
|
2003-05-01 15:35:24 +00:00
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
m_hidden = ! m_hidden; // toggle hidden state
|
|
|
|
if (isHidden())
|
2003-01-12 17:56:15 +00:00
|
|
|
frame.window.move(frame.x_hidden, frame.y_hidden);
|
2002-12-01 13:42:15 +00:00
|
|
|
else
|
2003-01-12 17:56:15 +00:00
|
|
|
frame.window.move(frame.x, frame.y);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
void Slit::loadClientList(const char *filename) {
|
|
|
|
if (filename == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_filename = filename; // save filename so we can save client list later
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
struct stat buf;
|
2003-01-12 17:56:15 +00:00
|
|
|
if (!stat(filename, &buf)) {
|
|
|
|
std::ifstream file(filename);
|
2002-12-01 13:42:15 +00:00
|
|
|
std::string name;
|
|
|
|
while (! file.eof()) {
|
|
|
|
name = "";
|
|
|
|
std::getline(file, name); // get the entire line
|
2003-01-12 17:56:15 +00:00
|
|
|
if (name.size() > 0) { // don't add client unless we have a valid line
|
2002-12-01 13:42:15 +00:00
|
|
|
SlitClient *client = new SlitClient(name.c_str());
|
2003-05-11 17:42:51 +00:00
|
|
|
m_client_list.push_back(client);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-05-29 06:21:59 +00:00
|
|
|
}
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
void Slit::updateClientmenu() {
|
|
|
|
// clear old items
|
2003-05-11 17:42:51 +00:00
|
|
|
m_clientlist_menu.removeAll();
|
|
|
|
m_clientlist_menu.setLabel("Clients");
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
FbTk::RefCount<FbTk::Command> cycle_up(new FbTk::SimpleCommand<Slit>(*this, &Slit::cycleClientsUp));
|
|
|
|
FbTk::RefCount<FbTk::Command> cycle_down(new FbTk::SimpleCommand<Slit>(*this, &Slit::cycleClientsDown));
|
2003-05-11 17:42:51 +00:00
|
|
|
m_clientlist_menu.insert("Cycle Up", cycle_up);
|
|
|
|
m_clientlist_menu.insert("Cycle Down", cycle_down);
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
FbTk::MenuItem *separator = new FbTk::MenuItem("-------");
|
|
|
|
separator->setEnabled(false);
|
2003-05-11 17:42:51 +00:00
|
|
|
m_clientlist_menu.insert(separator);
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
FbTk::RefCount<FbTk::Command> reconfig(new FbTk::SimpleCommand<Slit>(*this, &Slit::reconfigure));
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClients::iterator it = m_client_list.begin();
|
|
|
|
for (; it != m_client_list.end(); ++it) {
|
2003-02-20 16:41:22 +00:00
|
|
|
if ((*it) != 0 && (*it)->window != 0)
|
2003-05-11 17:42:51 +00:00
|
|
|
m_clientlist_menu.insert(new SlitClientMenuItem(*(*it), reconfig));
|
2003-01-12 17:56:15 +00:00
|
|
|
}
|
|
|
|
|
2003-05-11 17:42:51 +00:00
|
|
|
m_clientlist_menu.update();
|
2003-01-12 17:56:15 +00:00
|
|
|
}
|
|
|
|
|
2002-11-14 00:23:19 +00:00
|
|
|
void Slit::saveClientList() {
|
2003-01-12 17:56:15 +00:00
|
|
|
|
|
|
|
std::ofstream file(m_filename.c_str());
|
2003-05-11 17:42:51 +00:00
|
|
|
SlitClients::iterator it = m_client_list.begin();
|
|
|
|
SlitClients::iterator it_end = m_client_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
std::string prevName;
|
|
|
|
std::string name;
|
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
name = (*it)->match_name;
|
|
|
|
if (name != prevName)
|
|
|
|
file << name.c_str() << std::endl;
|
|
|
|
|
|
|
|
prevName = name;
|
|
|
|
}
|
2002-05-29 06:21:59 +00:00
|
|
|
}
|
2003-01-12 17:56:15 +00:00
|
|
|
|
2002-11-14 00:23:19 +00:00
|
|
|
void Slit::setAutoHide(bool val) {
|
2003-05-11 17:42:51 +00:00
|
|
|
m_do_auto_hide = val;
|
2003-04-16 16:18:06 +00:00
|
|
|
screen().saveSlitAutoHide(val);
|
2003-05-11 17:42:51 +00:00
|
|
|
if (doAutoHide()) {
|
|
|
|
if (! m_timer.isTiming()) {
|
|
|
|
if (m_slitmenu.isVisible())
|
|
|
|
m_timer.fireOnce(false);
|
|
|
|
m_timer.start();
|
2003-05-01 15:35:24 +00:00
|
|
|
}
|
2003-05-11 17:42:51 +00:00
|
|
|
}
|
2002-11-14 00:23:19 +00:00
|
|
|
}
|
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
void Slit::setupMenu() {
|
2002-12-01 13:42:15 +00:00
|
|
|
I18n *i18n = I18n::instance();
|
|
|
|
using namespace FBNLS;
|
2003-01-12 17:56:15 +00:00
|
|
|
using namespace FbTk;
|
|
|
|
|
2003-04-16 16:18:06 +00:00
|
|
|
FbTk::MacroCommand *s_a_reconf_macro = new FbTk::MacroCommand();
|
2003-05-13 21:12:18 +00:00
|
|
|
FbTk::MacroCommand *s_a_reconf_slit_macro = new FbTk::MacroCommand();
|
2003-04-16 16:18:06 +00:00
|
|
|
FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(*Fluxbox::instance(),
|
|
|
|
&Fluxbox::save_rc));
|
|
|
|
FbTk::RefCount<FbTk::Command> reconf_cmd(new FbCommands::ReconfigureFluxboxCmd());
|
2003-05-13 21:12:18 +00:00
|
|
|
FbTk::RefCount<FbTk::Command> reconf_slit_cmd(new FbTk::SimpleCommand<Slit>(*this, &Slit::reconfigure));
|
|
|
|
|
2003-04-16 16:18:06 +00:00
|
|
|
s_a_reconf_macro->add(saverc_cmd);
|
|
|
|
s_a_reconf_macro->add(reconf_cmd);
|
2003-05-13 21:12:18 +00:00
|
|
|
|
|
|
|
s_a_reconf_slit_macro->add(saverc_cmd);
|
|
|
|
s_a_reconf_slit_macro->add(reconf_slit_cmd);
|
|
|
|
|
2003-04-16 16:18:06 +00:00
|
|
|
FbTk::RefCount<FbTk::Command> save_and_reconfigure(s_a_reconf_macro);
|
2003-05-13 21:12:18 +00:00
|
|
|
FbTk::RefCount<FbTk::Command> save_and_reconfigure_slit(s_a_reconf_slit_macro);
|
2003-04-16 16:18:06 +00:00
|
|
|
|
2003-01-12 17:56:15 +00:00
|
|
|
// setup base menu
|
2003-05-11 17:42:51 +00:00
|
|
|
m_slitmenu.setLabel("Slit");
|
|
|
|
m_slitmenu.insert(i18n->getMessage(
|
|
|
|
CommonSet, CommonPlacementTitle,
|
|
|
|
"Placement"),
|
|
|
|
&m_placement_menu);
|
|
|
|
|
|
|
|
m_slitmenu.insert("Layer...", m_layermenu.get());
|
|
|
|
|
|
|
|
m_slitmenu.insert(new BoolMenuItem(i18n->getMessage(
|
|
|
|
CommonSet, CommonAutoHide,
|
|
|
|
"Auto hide"),
|
|
|
|
screen().doSlitAutoHide(),
|
2003-05-13 21:12:18 +00:00
|
|
|
save_and_reconfigure_slit));
|
|
|
|
|
|
|
|
FbTk::MenuItem *alpha_menuitem = new IntResMenuItem("Alpha",
|
|
|
|
screen().slitAlphaResource(),
|
|
|
|
0, 255);
|
|
|
|
alpha_menuitem->setCommand(save_and_reconfigure_slit);
|
|
|
|
m_slitmenu.insert(alpha_menuitem);
|
2003-05-11 17:42:51 +00:00
|
|
|
|
|
|
|
m_slitmenu.insert(new SlitDirMenuItem(i18n->getMessage(
|
|
|
|
SlitSet, SlitSlitDirection,
|
|
|
|
"Slit Direction"),
|
|
|
|
*this,
|
|
|
|
save_and_reconfigure));
|
|
|
|
m_slitmenu.insert("Clients", &m_clientlist_menu);
|
|
|
|
m_slitmenu.update();
|
2003-01-12 17:56:15 +00:00
|
|
|
|
|
|
|
// setup sub menu
|
2003-05-11 17:42:51 +00:00
|
|
|
m_placement_menu.setLabel(i18n->getMessage(
|
2003-01-12 17:56:15 +00:00
|
|
|
SlitSet, SlitSlitPlacement,
|
|
|
|
"Slit Placement"));
|
2003-05-11 17:42:51 +00:00
|
|
|
m_placement_menu.setMinimumSublevels(3);
|
|
|
|
m_placement_menu.setInternalMenu();
|
2003-01-12 17:56:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
// setup items in sub menu
|
|
|
|
struct {
|
|
|
|
int set;
|
|
|
|
int base;
|
|
|
|
const char *default_str;
|
|
|
|
Placement slit_placement;
|
|
|
|
} place_menu[] = {
|
|
|
|
{CommonSet, CommonPlacementTopLeft, "Top Left", Slit::TOPLEFT},
|
|
|
|
{CommonSet, CommonPlacementCenterLeft, "Center Left", Slit::CENTERLEFT},
|
|
|
|
{CommonSet, CommonPlacementBottomLeft, "Bottom Left", Slit::BOTTOMLEFT},
|
|
|
|
{CommonSet, CommonPlacementTopCenter, "Top Center", Slit::TOPCENTER},
|
|
|
|
{0, 0, 0, Slit::TOPLEFT}, // middle item, empty
|
|
|
|
{CommonSet, CommonPlacementBottomCenter, "Bottom Center", Slit::BOTTOMCENTER},
|
|
|
|
{CommonSet, CommonPlacementTopRight, "Top Right", Slit::TOPRIGHT},
|
|
|
|
{CommonSet, CommonPlacementCenterRight, "Center Right", Slit::CENTERRIGHT},
|
|
|
|
{CommonSet, CommonPlacementBottomRight, "Bottom Right", Slit::BOTTOMRIGHT}
|
|
|
|
};
|
|
|
|
// create items in sub menu
|
|
|
|
for (size_t i=0; i<9; ++i) {
|
|
|
|
if (place_menu[i].default_str == 0) {
|
2003-05-11 17:42:51 +00:00
|
|
|
m_placement_menu.insert("");
|
2002-12-01 13:42:15 +00:00
|
|
|
} else {
|
2003-01-12 17:56:15 +00:00
|
|
|
const char *i18n_str = i18n->getMessage(place_menu[i].set,
|
|
|
|
place_menu[i].base,
|
|
|
|
place_menu[i].default_str);
|
2003-05-11 17:42:51 +00:00
|
|
|
m_placement_menu.insert(new PlaceSlitMenuItem(i18n_str, *this,
|
2003-04-16 16:18:06 +00:00
|
|
|
place_menu[i].slit_placement,
|
|
|
|
save_and_reconfigure));
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
}
|
2003-01-12 17:56:15 +00:00
|
|
|
// finaly update sub menu
|
2003-05-11 17:42:51 +00:00
|
|
|
m_placement_menu.update();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
2003-04-16 16:18:06 +00:00
|
|
|
|
|
|
|
void Slit::moveToLayer(int layernum) {
|
|
|
|
m_layeritem->moveToLayer(layernum);
|
|
|
|
m_screen.saveSlitLayer((Fluxbox::Layer) layernum);
|
|
|
|
}
|