2001-12-11 20:47:02 +00:00
|
|
|
// Slit.cc for Blackbox - an X11 Window manager
|
|
|
|
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.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.
|
|
|
|
|
2002-09-08 19:48:03 +00:00
|
|
|
// $Id: Slit.cc,v 1.21 2002/09/08 19:48:03 fluxgen Exp $
|
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
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "../config.h"
|
|
|
|
#endif // HAVE_CONFIG_H
|
|
|
|
|
|
|
|
#ifdef SLIT
|
|
|
|
|
|
|
|
#include <X11/keysym.h>
|
|
|
|
|
|
|
|
#include "i18n.hh"
|
|
|
|
#include "fluxbox.hh"
|
|
|
|
#include "Image.hh"
|
|
|
|
#include "Screen.hh"
|
|
|
|
#include "Slit.hh"
|
|
|
|
#include "Toolbar.hh"
|
|
|
|
|
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
|
|
|
|
# include <sys/types.h>
|
|
|
|
# include <sys/stat.h>
|
|
|
|
#endif // HAVE_SYS_STAT_H
|
|
|
|
|
|
|
|
|
|
|
|
// Utility method for extracting name from window
|
|
|
|
namespace {
|
|
|
|
void getWMName(BScreen *screen, Window window, std::string& name) {
|
|
|
|
name = "";
|
|
|
|
|
|
|
|
if (screen != 0 && window != None) {
|
|
|
|
Display *display = screen->getBaseDisplay()->getXDisplay();
|
|
|
|
|
|
|
|
XTextProperty text_prop;
|
|
|
|
char **list;
|
|
|
|
int num;
|
|
|
|
I18n *i18n = I18n::instance();
|
|
|
|
|
|
|
|
if (XGetWMName(display, window, &text_prop)) {
|
|
|
|
if (text_prop.value && text_prop.nitems > 0) {
|
|
|
|
if (text_prop.encoding != XA_STRING) {
|
|
|
|
|
|
|
|
text_prop.nitems = strlen((char *) text_prop.value);
|
|
|
|
|
|
|
|
if ((XmbTextPropertyToTextList(display, &text_prop,
|
|
|
|
&list, &num) == Success) &&
|
|
|
|
(num > 0) && *list) {
|
|
|
|
name = static_cast<char *>(*list);
|
|
|
|
XFreeStringList(list);
|
|
|
|
} else
|
|
|
|
name = (char *)text_prop.value;
|
|
|
|
|
|
|
|
} else
|
|
|
|
name = (char *)text_prop.value;
|
|
|
|
} else
|
|
|
|
name = i18n->getMessage(
|
|
|
|
FBNLS::WindowSet, FBNLS::WindowUnnamed,
|
|
|
|
"Unnamed");
|
|
|
|
} else {
|
|
|
|
name = i18n->getMessage(
|
|
|
|
FBNLS::WindowSet, FBNLS::WindowUnnamed,
|
|
|
|
"Unnamed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}; // End anonymous namespace
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
Slit::Slit(BScreen *scr):screen(scr), timer(this), slitmenu(*this) {
|
2002-05-29 06:21:59 +00:00
|
|
|
assert(scr);
|
2001-12-11 20:47:02 +00:00
|
|
|
fluxbox = Fluxbox::instance();
|
|
|
|
|
|
|
|
on_top = screen->isSlitOnTop();
|
|
|
|
hidden = do_auto_hide = screen->doSlitAutoHide();
|
|
|
|
|
|
|
|
display = screen->getBaseDisplay()->getXDisplay();
|
|
|
|
frame.window = frame.pixmap = None;
|
|
|
|
|
2002-03-19 00:07:00 +00:00
|
|
|
|
|
|
|
timer.setTimeout(fluxbox->getAutoRaiseDelay());
|
|
|
|
timer.fireOnce(True);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
XSetWindowAttributes attrib;
|
|
|
|
unsigned long create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel |
|
2002-02-04 22:33:09 +00:00
|
|
|
CWColormap | CWOverrideRedirect | CWEventMask;
|
2001-12-11 20:47:02 +00:00
|
|
|
attrib.background_pixmap = None;
|
|
|
|
attrib.background_pixel = attrib.border_pixel =
|
2002-07-20 09:35:01 +00:00
|
|
|
screen->getBorderColor()->pixel();
|
|
|
|
attrib.colormap = screen->colormap();
|
2001-12-11 20:47:02 +00:00
|
|
|
attrib.override_redirect = True;
|
|
|
|
attrib.event_mask = SubstructureRedirectMask | ButtonPressMask |
|
2002-05-29 06:21:59 +00:00
|
|
|
EnterWindowMask | LeaveWindowMask;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
frame.x = frame.y = 0;
|
|
|
|
frame.width = frame.height = 1;
|
|
|
|
|
|
|
|
frame.window =
|
|
|
|
XCreateWindow(display, screen->getRootWindow(), frame.x, frame.y,
|
|
|
|
frame.width, frame.height, screen->getBorderWidth(),
|
2002-03-11 12:29:57 +00:00
|
|
|
screen->getDepth(), InputOutput, screen->getVisual(),
|
|
|
|
create_mask, &attrib);
|
2001-12-11 20:47:02 +00:00
|
|
|
fluxbox->saveSlitSearch(frame.window, this);
|
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
// Get client list for sorting purposes
|
|
|
|
loadClientList();
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
reconfigure();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Slit::~Slit() {
|
|
|
|
fluxbox->grab();
|
|
|
|
|
|
|
|
screen->getImageControl()->removeImage(frame.pixmap);
|
|
|
|
|
|
|
|
fluxbox->removeSlitSearch(frame.window);
|
|
|
|
|
|
|
|
XDestroyWindow(display, frame.window);
|
|
|
|
|
|
|
|
fluxbox->ungrab();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Slit::addClient(Window w) {
|
2002-05-08 14:12:28 +00:00
|
|
|
//Can't add non existent window
|
|
|
|
if (w == None)
|
|
|
|
return;
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
fluxbox->grab();
|
|
|
|
if (fluxbox->validateWindow(w)) {
|
2002-05-29 06:21:59 +00:00
|
|
|
// Look for slot in client list by name
|
|
|
|
SlitClient *client = 0;
|
|
|
|
std::string match_name;
|
|
|
|
::getWMName(screen, w, match_name);
|
|
|
|
SlitClients::iterator it = clientList.begin();
|
|
|
|
SlitClients::iterator it_end = clientList.end();
|
|
|
|
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);
|
|
|
|
client->initialize(screen, w);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Otherwise keep looking for an unused match or a non-match
|
|
|
|
found_match = true; // Possibly redundant
|
|
|
|
|
|
|
|
} else if (found_match) {
|
|
|
|
// Insert before first non-match after a previously found match?
|
|
|
|
client = new SlitClient(screen, w);
|
|
|
|
clientList.insert(it, client);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Append to client list?
|
|
|
|
if (client == 0) {
|
|
|
|
client = new SlitClient(screen, w);
|
|
|
|
clientList.push_back(client);
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
XWMHints *wmhints = XGetWMHints(display, w);
|
|
|
|
|
|
|
|
if (wmhints) {
|
|
|
|
if ((wmhints->flags & IconWindowHint) &&
|
|
|
|
(wmhints->icon_window != None)) {
|
|
|
|
XMoveWindow(display, client->client_window, screen->getWidth() + 10,
|
2002-02-04 22:33:09 +00:00
|
|
|
screen->getHeight() + 10);
|
|
|
|
XMapWindow(display, client->client_window);
|
2001-12-11 20:47:02 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
XWindowAttributes attrib;
|
2002-03-11 12:29:57 +00:00
|
|
|
#ifdef KDE
|
2001-12-11 20:47:02 +00:00
|
|
|
//Check and see if new client is a KDE dock applet
|
|
|
|
//If so force reasonable size
|
|
|
|
bool iskdedockapp=false;
|
|
|
|
Atom ajunk;
|
|
|
|
int ijunk;
|
|
|
|
unsigned long *data = (unsigned long *) 0, uljunk;
|
|
|
|
|
|
|
|
// Check if KDE v2.x dock applet
|
|
|
|
if (XGetWindowProperty(fluxbox->getXDisplay(), w,
|
2002-02-04 22:33:09 +00:00
|
|
|
fluxbox->getKWM2DockwindowAtom(), 0l, 1l, False,
|
|
|
|
fluxbox->getKWM2DockwindowAtom(),
|
|
|
|
&ajunk, &ijunk, &uljunk, &uljunk,
|
|
|
|
(unsigned char **) &data) == Success) {
|
2001-12-11 20:47:02 +00:00
|
|
|
iskdedockapp = (data && data[0] != 0);
|
|
|
|
XFree((char *) data);
|
2002-02-04 22:33:09 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
// Check if KDE v1.x dock applet
|
|
|
|
if (!iskdedockapp) {
|
|
|
|
if (XGetWindowProperty(fluxbox->getXDisplay(), w,
|
2002-02-04 22:33:09 +00:00
|
|
|
fluxbox->getKWM1DockwindowAtom(), 0l, 1l, False,
|
|
|
|
fluxbox->getKWM1DockwindowAtom(),
|
|
|
|
&ajunk, &ijunk, &uljunk, &uljunk,
|
|
|
|
(unsigned char **) &data) == Success) {
|
2001-12-11 20:47:02 +00:00
|
|
|
iskdedockapp = (data && data[0] != 0);
|
2002-02-04 22:33:09 +00:00
|
|
|
XFree((char *) data);
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (iskdedockapp)
|
|
|
|
client->width = client->height = 24;
|
2002-03-11 12:29:57 +00:00
|
|
|
else
|
|
|
|
#endif // KDE
|
|
|
|
{
|
2001-12-11 20:47:02 +00:00
|
|
|
if (XGetWindowAttributes(display, client->window, &attrib)) {
|
|
|
|
client->width = attrib.width;
|
|
|
|
client->height = attrib.height;
|
2002-03-11 12:29:57 +00:00
|
|
|
} else {
|
2001-12-11 20:47:02 +00:00
|
|
|
client->width = client->height = 64;
|
2002-03-11 12:29:57 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
XSetWindowBorderWidth(display, client->window, 0);
|
|
|
|
|
|
|
|
XSelectInput(display, frame.window, NoEventMask);
|
|
|
|
XSelectInput(display, client->window, NoEventMask);
|
|
|
|
|
|
|
|
XReparentWindow(display, client->window, frame.window, 0, 0);
|
2002-02-04 22:33:09 +00:00
|
|
|
XMapRaised(display, client->window);
|
2001-12-11 20:47:02 +00:00
|
|
|
XChangeSaveSet(display, client->window, SetModeInsert);
|
|
|
|
|
|
|
|
XSelectInput(display, frame.window, SubstructureRedirectMask |
|
2002-02-04 22:33:09 +00:00
|
|
|
ButtonPressMask | EnterWindowMask | LeaveWindowMask);
|
2001-12-11 20:47:02 +00:00
|
|
|
XSelectInput(display, client->window, StructureNotifyMask |
|
2002-02-04 22:33:09 +00:00
|
|
|
SubstructureNotifyMask | EnterWindowMask);
|
2001-12-11 20:47:02 +00:00
|
|
|
XFlush(display);
|
|
|
|
|
|
|
|
fluxbox->saveSlitSearch(client->client_window, this);
|
|
|
|
fluxbox->saveSlitSearch(client->icon_window, this);
|
|
|
|
reconfigure();
|
2002-05-29 06:21:59 +00:00
|
|
|
|
|
|
|
saveClientList();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fluxbox->ungrab();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
void Slit::removeClient(SlitClient *client, bool remap, bool destroy) {
|
2001-12-11 20:47:02 +00:00
|
|
|
fluxbox->removeSlitSearch(client->client_window);
|
|
|
|
fluxbox->removeSlitSearch(client->icon_window);
|
2002-02-04 22:33:09 +00:00
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
// Destructive removal?
|
|
|
|
if (destroy)
|
|
|
|
clientList.remove(client);
|
|
|
|
else // Clear the window info, but keep around to help future sorting?
|
|
|
|
client->initialize();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
screen->removeNetizen(client->window);
|
|
|
|
|
|
|
|
if (remap && fluxbox->validateWindow(client->window)) {
|
|
|
|
XSelectInput(display, frame.window, NoEventMask);
|
|
|
|
XSelectInput(display, client->window, NoEventMask);
|
|
|
|
XReparentWindow(display, client->window, screen->getRootWindow(),
|
2002-02-04 22:33:09 +00:00
|
|
|
client->x, client->y);
|
2001-12-11 20:47:02 +00:00
|
|
|
XChangeSaveSet(display, client->window, SetModeDelete);
|
|
|
|
XSelectInput(display, frame.window, SubstructureRedirectMask |
|
2002-02-04 22:33:09 +00:00
|
|
|
ButtonPressMask | EnterWindowMask | LeaveWindowMask);
|
2001-12-11 20:47:02 +00:00
|
|
|
XFlush(display);
|
|
|
|
}
|
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
// Destructive removal?
|
|
|
|
if (destroy)
|
|
|
|
delete client;
|
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
|
|
|
fluxbox->grab();
|
|
|
|
|
2002-02-04 22:33:09 +00:00
|
|
|
bool reconf = false;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-02-04 22:33:09 +00:00
|
|
|
SlitClients::iterator it = clientList.begin();
|
|
|
|
SlitClients::iterator it_end = clientList.end();
|
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
if ((*it)->window == w) {
|
2002-05-29 06:21:59 +00:00
|
|
|
removeClient((*it), remap, false);
|
2002-02-04 22:33:09 +00:00
|
|
|
reconf = true;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2002-02-04 22:33:09 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
if (reconf) reconfigure();
|
|
|
|
|
|
|
|
fluxbox->ungrab();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Slit::reconfigure(void) {
|
|
|
|
frame.width = 0;
|
|
|
|
frame.height = 0;
|
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
// Need to count windows because not all client list entries
|
|
|
|
// actually correspond to mapped windows.
|
|
|
|
int num_windows = 0;
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
switch (screen->getSlitDirection()) {
|
2002-01-11 10:21:44 +00:00
|
|
|
case VERTICAL:
|
2002-02-04 22:33:09 +00:00
|
|
|
{
|
|
|
|
SlitClients::iterator it = clientList.begin();
|
|
|
|
SlitClients::iterator it_end = clientList.end();
|
|
|
|
for (; it != it_end; ++it) {
|
2002-05-29 06:21:59 +00:00
|
|
|
//client created window?
|
|
|
|
if ((*it)->window != None) {
|
|
|
|
num_windows++;
|
|
|
|
frame.height += (*it)->height + screen->getBevelWidth();
|
|
|
|
|
|
|
|
//frame width < client window?
|
|
|
|
if (frame.width < (*it)->width)
|
|
|
|
frame.width = (*it)->width;
|
|
|
|
}
|
2002-02-04 22:33:09 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (frame.width < 1)
|
|
|
|
frame.width = 1;
|
|
|
|
else
|
|
|
|
frame.width += (screen->getBevelWidth() * 2);
|
|
|
|
|
|
|
|
if (frame.height < 1)
|
|
|
|
frame.height = 1;
|
|
|
|
else
|
|
|
|
frame.height += screen->getBevelWidth();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
2002-01-11 10:21:44 +00:00
|
|
|
case HORIZONTAL:
|
2002-02-04 22:33:09 +00:00
|
|
|
{
|
|
|
|
SlitClients::iterator it = clientList.begin();
|
|
|
|
SlitClients::iterator it_end = clientList.end();
|
|
|
|
for (; it != it_end; ++it) {
|
2002-05-29 06:21:59 +00:00
|
|
|
//client created window?
|
|
|
|
if ((*it)->window != None) {
|
|
|
|
num_windows++;
|
|
|
|
frame.width += (*it)->width + screen->getBevelWidth();
|
|
|
|
//frame height < client height?
|
|
|
|
if (frame.height < (*it)->height)
|
|
|
|
frame.height = (*it)->height;
|
|
|
|
}
|
2002-02-04 22:33:09 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (frame.width < 1)
|
|
|
|
frame.width = 1;
|
|
|
|
else
|
|
|
|
frame.width += screen->getBevelWidth();
|
|
|
|
|
|
|
|
if (frame.height < 1)
|
|
|
|
frame.height = 1;
|
|
|
|
else
|
|
|
|
frame.height += (screen->getBevelWidth() * 2);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
reposition();
|
|
|
|
|
|
|
|
XSetWindowBorderWidth(display ,frame.window, screen->getBorderWidth());
|
|
|
|
XSetWindowBorder(display, frame.window,
|
2002-07-20 09:35:01 +00:00
|
|
|
screen->getBorderColor()->pixel());
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
//did we actually use slit slots
|
|
|
|
if (num_windows == 0)
|
2001-12-11 20:47:02 +00:00
|
|
|
XUnmapWindow(display, frame.window);
|
|
|
|
else
|
|
|
|
XMapWindow(display, frame.window);
|
|
|
|
|
|
|
|
Pixmap tmp = frame.pixmap;
|
|
|
|
BImageControl *image_ctrl = screen->getImageControl();
|
2002-07-23 18:38:31 +00:00
|
|
|
const FbTk::Texture *texture = &(screen->getTheme()->getSlitTexture());
|
2002-07-23 17:11:59 +00:00
|
|
|
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
|
2001-12-11 20:47:02 +00:00
|
|
|
frame.pixmap = None;
|
|
|
|
XSetWindowBackground(display, frame.window,
|
2002-07-20 09:35:01 +00:00
|
|
|
texture->color().pixel());
|
2001-12-11 20:47:02 +00:00
|
|
|
} else {
|
|
|
|
frame.pixmap = image_ctrl->renderImage(frame.width, frame.height,
|
2002-02-04 22:33:09 +00:00
|
|
|
texture);
|
2001-12-11 20:47:02 +00:00
|
|
|
XSetWindowBackgroundPixmap(display, frame.window, frame.pixmap);
|
|
|
|
}
|
2002-05-29 06:21:59 +00:00
|
|
|
|
|
|
|
if (tmp)
|
|
|
|
image_ctrl->removeImage(tmp);
|
2001-12-11 20:47:02 +00:00
|
|
|
XClearWindow(display, frame.window);
|
|
|
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
switch (screen->getSlitDirection()) {
|
2002-01-11 10:21:44 +00:00
|
|
|
case VERTICAL:
|
2001-12-11 20:47:02 +00:00
|
|
|
x = 0;
|
|
|
|
y = screen->getBevelWidth();
|
|
|
|
|
2002-02-04 22:33:09 +00:00
|
|
|
{
|
|
|
|
SlitClients::iterator it = clientList.begin();
|
|
|
|
SlitClients::iterator it_end = clientList.end();
|
|
|
|
for (; it != it_end; ++it) {
|
2002-05-29 06:21:59 +00:00
|
|
|
//client created window?
|
|
|
|
if ((*it)->window == None)
|
|
|
|
continue;
|
|
|
|
|
2002-02-04 22:33:09 +00:00
|
|
|
x = (frame.width - (*it)->width) / 2;
|
|
|
|
|
|
|
|
XMoveResizeWindow(display, (*it)->window, x, y,
|
|
|
|
(*it)->width, (*it)->height);
|
|
|
|
XMapWindow(display, (*it)->window);
|
|
|
|
|
|
|
|
// for ICCCM compliance
|
|
|
|
(*it)->x = x;
|
|
|
|
(*it)->y = y;
|
|
|
|
|
|
|
|
XEvent event;
|
|
|
|
event.type = ConfigureNotify;
|
|
|
|
|
|
|
|
event.xconfigure.display = display;
|
|
|
|
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;
|
|
|
|
event.xconfigure.above = frame.window;
|
|
|
|
event.xconfigure.override_redirect = False;
|
|
|
|
|
|
|
|
XSendEvent(display, (*it)->window, False, StructureNotifyMask,
|
|
|
|
&event);
|
|
|
|
|
|
|
|
y += (*it)->height + screen->getBevelWidth();
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
2002-01-11 10:21:44 +00:00
|
|
|
case HORIZONTAL:
|
2001-12-11 20:47:02 +00:00
|
|
|
x = screen->getBevelWidth();
|
|
|
|
y = 0;
|
|
|
|
|
2002-02-04 22:33:09 +00:00
|
|
|
{
|
|
|
|
SlitClients::iterator it = clientList.begin();
|
|
|
|
SlitClients::iterator it_end = clientList.end();
|
|
|
|
for (; it != it_end; ++it) {
|
2002-05-29 06:21:59 +00:00
|
|
|
//client created window?
|
|
|
|
if ((*it)->window == None)
|
|
|
|
continue;
|
|
|
|
|
2002-02-04 22:33:09 +00:00
|
|
|
y = (frame.height - (*it)->height) / 2;
|
|
|
|
|
|
|
|
XMoveResizeWindow(display, (*it)->window, x, y,
|
|
|
|
(*it)->width, (*it)->height);
|
|
|
|
XMapWindow(display, (*it)->window);
|
|
|
|
|
|
|
|
// for ICCCM compliance
|
|
|
|
(*it)->x = x;
|
|
|
|
(*it)->y = y;
|
|
|
|
|
|
|
|
XEvent event;
|
|
|
|
event.type = ConfigureNotify;
|
|
|
|
|
|
|
|
event.xconfigure.display = display;
|
|
|
|
event.xconfigure.event = (*it)->window;
|
|
|
|
event.xconfigure.window = (*it)->window;
|
|
|
|
event.xconfigure.x = frame.x + x + screen->getBorderWidth();
|
|
|
|
event.xconfigure.y = frame.y + y + screen->getBorderWidth();
|
|
|
|
event.xconfigure.width = (*it)->width;
|
|
|
|
event.xconfigure.height = (*it)->height;
|
|
|
|
event.xconfigure.border_width = 0;
|
|
|
|
event.xconfigure.above = frame.window;
|
|
|
|
event.xconfigure.override_redirect = False;
|
|
|
|
|
|
|
|
XSendEvent(display, (*it)->window, False, StructureNotifyMask,
|
|
|
|
&event);
|
|
|
|
|
|
|
|
x += (*it)->width + screen->getBevelWidth();
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2002-03-19 00:07:00 +00:00
|
|
|
slitmenu.reconfigure();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 21:51:07 +00:00
|
|
|
void Slit::reposition() {
|
2002-03-19 14:30:43 +00:00
|
|
|
int head_x = 0,
|
|
|
|
head_y = 0,
|
|
|
|
head_w,
|
|
|
|
head_h;
|
2002-07-19 16:10:18 +00:00
|
|
|
#ifdef XINERAMA
|
2002-03-19 14:30:43 +00:00
|
|
|
if (screen->hasXinerama()) {
|
|
|
|
unsigned int head = screen->getSlitOnHead();
|
|
|
|
|
|
|
|
head_x = screen->getHeadX(head);
|
|
|
|
head_y = screen->getHeadY(head);
|
|
|
|
head_w = screen->getHeadWidth(head);
|
|
|
|
head_h = screen->getHeadHeight(head);
|
|
|
|
} else {
|
|
|
|
head_w = screen->getWidth();
|
|
|
|
head_h = screen->getHeight();
|
|
|
|
}
|
|
|
|
#else // !XINERAMA
|
|
|
|
head_w = screen->getWidth();
|
|
|
|
head_h = screen->getHeight();
|
|
|
|
#endif // XINERAMA
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
// place the slit in the appropriate place
|
|
|
|
switch (screen->getSlitPlacement()) {
|
2002-01-11 10:21:44 +00:00
|
|
|
case TOPLEFT:
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x = head_x;
|
|
|
|
frame.y = head_y;
|
2002-01-11 10:21:44 +00:00
|
|
|
if (screen->getSlitDirection() == VERTICAL) {
|
2002-02-04 22:33:09 +00:00
|
|
|
frame.x_hidden = screen->getBevelWidth() -
|
|
|
|
screen->getBorderWidth() - frame.width;
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.y_hidden = head_y;
|
2001-12-11 20:47:02 +00:00
|
|
|
} else {
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x_hidden = head_x;
|
2002-02-04 22:33:09 +00:00
|
|
|
frame.y_hidden = screen->getBevelWidth() -
|
|
|
|
screen->getBorderWidth() - frame.height;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2002-01-11 10:21:44 +00:00
|
|
|
case CENTERLEFT:
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x = head_x;
|
|
|
|
frame.y = head_y + (head_h - frame.height) / 2;
|
|
|
|
frame.x_hidden = head_x + screen->getBevelWidth() -
|
2002-02-04 22:33:09 +00:00
|
|
|
screen->getBorderWidth() - frame.width;
|
2001-12-11 20:47:02 +00:00
|
|
|
frame.y_hidden = frame.y;
|
|
|
|
break;
|
|
|
|
|
2002-01-11 10:21:44 +00:00
|
|
|
case BOTTOMLEFT:
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x = head_x;
|
|
|
|
frame.y = head_h - frame.height - screen->getBorderWidth2x();
|
2002-01-11 10:21:44 +00:00
|
|
|
if (screen->getSlitDirection() == VERTICAL) {
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x_hidden = head_x + screen->getBevelWidth() -
|
|
|
|
screen->getBorderWidth() - frame.width;
|
2001-12-11 20:47:02 +00:00
|
|
|
frame.y_hidden = frame.y;
|
|
|
|
} else {
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x_hidden = head_x;
|
|
|
|
frame.y_hidden = head_y + head_h -
|
2002-02-04 22:33:09 +00:00
|
|
|
screen->getBevelWidth() - screen->getBorderWidth();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2002-01-11 10:21:44 +00:00
|
|
|
case TOPCENTER:
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x = head_x + ((head_w - frame.width) / 2);
|
|
|
|
frame.y = head_y;
|
2001-12-11 20:47:02 +00:00
|
|
|
frame.x_hidden = frame.x;
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.y_hidden = head_y + screen->getBevelWidth() -
|
2002-02-04 22:33:09 +00:00
|
|
|
screen->getBorderWidth() - frame.height;
|
2001-12-11 20:47:02 +00:00
|
|
|
break;
|
|
|
|
|
2002-01-11 10:21:44 +00:00
|
|
|
case BOTTOMCENTER:
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x = head_x + ((head_w - frame.width) / 2);
|
|
|
|
frame.y = head_y + head_h - frame.height - screen->getBorderWidth2x();
|
2001-12-11 20:47:02 +00:00
|
|
|
frame.x_hidden = frame.x;
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.y_hidden = head_y + head_h -
|
2002-02-04 22:33:09 +00:00
|
|
|
screen->getBevelWidth() - screen->getBorderWidth();
|
2001-12-11 20:47:02 +00:00
|
|
|
break;
|
|
|
|
|
2002-01-11 10:21:44 +00:00
|
|
|
case TOPRIGHT:
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x = head_x + head_w - frame.width - screen->getBorderWidth2x();
|
|
|
|
frame.y = head_y;
|
2002-01-11 10:21:44 +00:00
|
|
|
if (screen->getSlitDirection() == VERTICAL) {
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x_hidden = head_x + head_w -
|
2002-02-04 22:33:09 +00:00
|
|
|
screen->getBevelWidth() - screen->getBorderWidth();
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.y_hidden = head_y;
|
2001-12-11 20:47:02 +00:00
|
|
|
} else {
|
|
|
|
frame.x_hidden = frame.x;
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.y_hidden = head_y + screen->getBevelWidth() -
|
2002-02-04 22:33:09 +00:00
|
|
|
screen->getBorderWidth() - frame.height;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2002-01-11 10:21:44 +00:00
|
|
|
case CENTERRIGHT:
|
2001-12-11 20:47:02 +00:00
|
|
|
default:
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x = head_x + head_w - frame.width - screen->getBorderWidth2x();
|
|
|
|
frame.y = head_y + ((head_h - frame.height) / 2);
|
|
|
|
frame.x_hidden = head_x + head_w -
|
2002-02-04 22:33:09 +00:00
|
|
|
screen->getBevelWidth() - screen->getBorderWidth();
|
2001-12-11 20:47:02 +00:00
|
|
|
frame.y_hidden = frame.y;
|
|
|
|
break;
|
|
|
|
|
2002-01-11 10:21:44 +00:00
|
|
|
case BOTTOMRIGHT:
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x = head_x + head_w - frame.width - screen->getBorderWidth2x();
|
|
|
|
frame.y = head_y + head_h - frame.height - screen->getBorderWidth2x();
|
2002-01-11 10:21:44 +00:00
|
|
|
if (screen->getSlitDirection() == VERTICAL) {
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.x_hidden = head_x + head_w -
|
2002-02-04 22:33:09 +00:00
|
|
|
screen->getBevelWidth() - screen->getBorderWidth();
|
2001-12-11 20:47:02 +00:00
|
|
|
frame.y_hidden = frame.y;
|
|
|
|
} else {
|
|
|
|
frame.x_hidden = frame.x;
|
2002-03-19 14:30:43 +00:00
|
|
|
frame.y_hidden = head_y + head_h -
|
2002-02-04 22:33:09 +00:00
|
|
|
screen->getBevelWidth() - screen->getBorderWidth();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Toolbar *tbar = screen->getToolbar();
|
|
|
|
int sw = frame.width + screen->getBorderWidth2x(),
|
2002-02-04 22:33:09 +00:00
|
|
|
sh = frame.height + screen->getBorderWidth2x(),
|
|
|
|
tw = tbar->getWidth() + screen->getBorderWidth(),
|
|
|
|
th = tbar->getHeight() + screen->getBorderWidth();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
if (tbar->getX() < frame.x + sw && tbar->getX() + tw > frame.x &&
|
|
|
|
tbar->getY() < frame.y + sh && tbar->getY() + th > frame.y) {
|
|
|
|
if (frame.y < th) {
|
|
|
|
frame.y += tbar->getExposedHeight();
|
2002-01-11 10:21:44 +00:00
|
|
|
if (screen->getSlitDirection() == VERTICAL)
|
2001-12-11 20:47:02 +00:00
|
|
|
frame.y_hidden += tbar->getExposedHeight();
|
|
|
|
else
|
2002-02-04 22:33:09 +00:00
|
|
|
frame.y_hidden = frame.y;
|
2001-12-11 20:47:02 +00:00
|
|
|
} else {
|
|
|
|
frame.y -= tbar->getExposedHeight();
|
2002-01-11 10:21:44 +00:00
|
|
|
if (screen->getSlitDirection() == VERTICAL)
|
2001-12-11 20:47:02 +00:00
|
|
|
frame.y_hidden -= tbar->getExposedHeight();
|
|
|
|
else
|
2002-02-04 22:33:09 +00:00
|
|
|
frame.y_hidden = frame.y;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hidden)
|
|
|
|
XMoveResizeWindow(display, frame.window, frame.x_hidden,
|
2002-02-04 22:33:09 +00:00
|
|
|
frame.y_hidden, frame.width, frame.height);
|
2001-12-11 20:47:02 +00:00
|
|
|
else
|
|
|
|
XMoveResizeWindow(display, frame.window, frame.x,
|
2002-02-04 22:33:09 +00:00
|
|
|
frame.y, frame.width, frame.height);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 21:51:07 +00:00
|
|
|
void Slit::shutdown() {
|
2002-05-29 06:21:59 +00:00
|
|
|
saveClientList();
|
2002-02-04 22:33:09 +00:00
|
|
|
while (clientList.size() != 0)
|
2002-05-29 06:21:59 +00:00
|
|
|
removeClient(clientList.front(), true, true);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Slit::buttonPressEvent(XButtonEvent *e) {
|
|
|
|
if (e->window != frame.window) return;
|
|
|
|
|
|
|
|
if (e->button == Button1 && (! on_top)) {
|
2002-09-08 19:48:03 +00:00
|
|
|
Workspace::Stack st;
|
|
|
|
st.push_back(frame.window);
|
|
|
|
screen->raiseWindows(st);
|
2001-12-11 20:47:02 +00:00
|
|
|
} else if (e->button == Button2 && (! on_top)) {
|
|
|
|
XLowerWindow(display, frame.window);
|
|
|
|
} else if (e->button == Button3) {
|
2002-03-19 00:07:00 +00:00
|
|
|
if (! slitmenu.isVisible()) {
|
2002-04-08 22:36:30 +00:00
|
|
|
int x = e->x_root - (slitmenu.width() / 2),
|
|
|
|
y = e->y_root - (slitmenu.height() / 2);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
if (x < 0)
|
|
|
|
x = 0;
|
2002-04-08 22:36:30 +00:00
|
|
|
else if (x + slitmenu.width() > screen->getWidth())
|
|
|
|
x = screen->getWidth() - slitmenu.width();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
if (y < 0)
|
|
|
|
y = 0;
|
2002-04-08 22:36:30 +00:00
|
|
|
else if (y + slitmenu.height() > screen->getHeight())
|
|
|
|
y = screen->getHeight() - slitmenu.height();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-03-19 00:07:00 +00:00
|
|
|
slitmenu.move(x, y);
|
|
|
|
slitmenu.show();
|
2001-12-11 20:47:02 +00:00
|
|
|
} else
|
2002-03-19 00:07:00 +00:00
|
|
|
slitmenu.hide();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Slit::enterNotifyEvent(XCrossingEvent *) {
|
|
|
|
if (! do_auto_hide)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (hidden) {
|
2002-08-14 21:51:07 +00:00
|
|
|
if (! timer.isTiming())
|
|
|
|
timer.start();
|
2001-12-11 20:47:02 +00:00
|
|
|
} else {
|
2002-08-14 21:51:07 +00:00
|
|
|
if (timer.isTiming())
|
|
|
|
timer.stop();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Slit::leaveNotifyEvent(XCrossingEvent *) {
|
|
|
|
if (! do_auto_hide)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (hidden) {
|
2002-08-14 21:51:07 +00:00
|
|
|
if (timer.isTiming())
|
|
|
|
timer.stop();
|
2002-03-19 00:07:00 +00:00
|
|
|
} else if (! slitmenu.isVisible()) {
|
2002-08-14 21:51:07 +00:00
|
|
|
if (! timer.isTiming())
|
|
|
|
timer.start();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Slit::configureRequestEvent(XConfigureRequestEvent *e) {
|
|
|
|
fluxbox->grab();
|
|
|
|
|
|
|
|
if (fluxbox->validateWindow(e->window)) {
|
2002-02-04 22:33:09 +00:00
|
|
|
bool reconf = false;
|
2001-12-11 20:47:02 +00:00
|
|
|
XWindowChanges xwc;
|
|
|
|
|
|
|
|
xwc.x = e->x;
|
|
|
|
xwc.y = e->y;
|
|
|
|
xwc.width = e->width;
|
|
|
|
xwc.height = e->height;
|
|
|
|
xwc.border_width = 0;
|
|
|
|
xwc.sibling = e->above;
|
|
|
|
xwc.stack_mode = e->detail;
|
|
|
|
|
|
|
|
XConfigureWindow(display, e->window, e->value_mask, &xwc);
|
|
|
|
|
2002-02-04 22:33:09 +00:00
|
|
|
SlitClients::iterator it = clientList.begin();
|
|
|
|
SlitClients::iterator it_end = clientList.end();
|
|
|
|
for (; it != it_end; ++it)
|
|
|
|
if ((*it)->window == e->window)
|
|
|
|
if ((*it)->width != ((unsigned) e->width) ||
|
|
|
|
(*it)->height != ((unsigned) e->height)) {
|
|
|
|
(*it)->width = (unsigned) e->width;
|
|
|
|
(*it)->height = (unsigned) e->height;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-02-04 22:33:09 +00:00
|
|
|
reconf = true;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (reconf) reconfigure();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
fluxbox->ungrab();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 21:51:07 +00:00
|
|
|
void Slit::timeout() {
|
2001-12-11 20:47:02 +00:00
|
|
|
hidden = ! hidden;
|
|
|
|
if (hidden)
|
|
|
|
XMoveWindow(display, frame.window, frame.x_hidden, frame.y_hidden);
|
|
|
|
else
|
|
|
|
XMoveWindow(display, frame.window, frame.x, frame.y);
|
|
|
|
}
|
|
|
|
|
2002-08-14 21:51:07 +00:00
|
|
|
void Slit::loadClientList() {
|
2002-05-29 06:21:59 +00:00
|
|
|
const std::string &filename = fluxbox->getSlitlistFilename();
|
|
|
|
struct stat buf;
|
2002-08-14 21:51:07 +00:00
|
|
|
if (!stat(filename.c_str(), &buf)) {
|
2002-05-29 06:21:59 +00:00
|
|
|
std::ifstream file(fluxbox->getSlitlistFilename().c_str());
|
|
|
|
std::string name;
|
|
|
|
while (! file.eof()) {
|
|
|
|
name = "";
|
2002-07-19 16:10:18 +00:00
|
|
|
std::getline(file, name); // get the entire line
|
2002-05-29 06:21:59 +00:00
|
|
|
if (name.size() > 0) {
|
|
|
|
SlitClient *client = new SlitClient(name.c_str());
|
|
|
|
clientList.push_back(client);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Slit::saveClientList(void) {
|
|
|
|
const std::string &filename = fluxbox->getSlitlistFilename();
|
|
|
|
std::ofstream file(filename.c_str());
|
|
|
|
SlitClients::iterator it = clientList.begin();
|
|
|
|
SlitClients::iterator it_end = clientList.end();
|
|
|
|
std::string prevName;
|
|
|
|
std::string name;
|
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
name = (*it)->match_name;
|
|
|
|
if (name != prevName)
|
|
|
|
file << name.c_str() << std::endl;
|
2002-07-19 16:10:18 +00:00
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
prevName = name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
Slitmenu::Slitmenu(Slit &sl) : Basemenu(sl.screen),
|
|
|
|
slit(sl) {
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
I18n *i18n = I18n::instance();
|
2002-04-04 11:28:19 +00:00
|
|
|
using namespace FBNLS;
|
2001-12-11 20:47:02 +00:00
|
|
|
setLabel(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
SlitSet, SlitSlitTitle,
|
|
|
|
"Slit"));
|
2001-12-11 20:47:02 +00:00
|
|
|
setInternalMenu();
|
|
|
|
|
|
|
|
directionmenu = new Directionmenu(this);
|
|
|
|
placementmenu = new Placementmenu(this);
|
2002-03-19 14:30:43 +00:00
|
|
|
#ifdef XINERAMA
|
2002-05-08 14:12:28 +00:00
|
|
|
if (screen()->hasXinerama()) { // only create if we need
|
2002-03-19 14:30:43 +00:00
|
|
|
headmenu = new Headmenu(this);
|
|
|
|
}
|
|
|
|
#endif // XINERAMA
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonDirectionTitle,
|
|
|
|
"Direction"),
|
2001-12-11 20:47:02 +00:00
|
|
|
directionmenu);
|
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonPlacementTitle,
|
|
|
|
"Placement"),
|
2001-12-11 20:47:02 +00:00
|
|
|
placementmenu);
|
2002-03-19 14:30:43 +00:00
|
|
|
|
|
|
|
#ifdef XINERAMA
|
|
|
|
//TODO: NLS
|
2002-05-08 14:12:28 +00:00
|
|
|
if (screen()->hasXinerama()) {
|
2002-03-19 14:30:43 +00:00
|
|
|
insert(i18n->getMessage(0, 0, "Place on Head"), headmenu);
|
|
|
|
}
|
|
|
|
#endif // XINERAMA
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonAlwaysOnTop,
|
|
|
|
"Always on top"), 1);
|
2001-12-11 20:47:02 +00:00
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonAutoHide,
|
|
|
|
"Auto hide"), 2);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
setItemSelected(2, slit.isOnTop());
|
|
|
|
setItemSelected(3, slit.doAutoHide());
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
update();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 21:51:07 +00:00
|
|
|
Slitmenu::~Slitmenu() {
|
2001-12-11 20:47:02 +00:00
|
|
|
delete directionmenu;
|
|
|
|
delete placementmenu;
|
2002-03-19 14:30:43 +00:00
|
|
|
#ifdef XINERAMA
|
2002-05-08 14:12:28 +00:00
|
|
|
if (screen()->hasXinerama()) {
|
2002-03-19 14:30:43 +00:00
|
|
|
delete headmenu;
|
|
|
|
}
|
|
|
|
#endif // XINERAMA
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-04-03 12:08:54 +00:00
|
|
|
void Slitmenu::itemSelected(int button, unsigned int index) {
|
2001-12-11 20:47:02 +00:00
|
|
|
if (button == 1) {
|
|
|
|
BasemenuItem *item = find(index);
|
|
|
|
if (! item) return;
|
|
|
|
|
|
|
|
switch (item->function()) {
|
|
|
|
case 1: // always on top
|
2002-04-03 12:08:54 +00:00
|
|
|
{
|
2002-05-08 14:12:28 +00:00
|
|
|
bool change = ((slit.isOnTop()) ? false : true);
|
|
|
|
slit.on_top = change;
|
|
|
|
screen()->saveSlitOnTop(change);
|
2002-04-03 12:08:54 +00:00
|
|
|
setItemSelected(2, change);
|
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
if (slit.isOnTop())
|
2002-09-08 19:48:03 +00:00
|
|
|
screen()->raiseWindows(Workspace::Stack());
|
2002-05-08 14:12:28 +00:00
|
|
|
|
2002-04-03 12:08:54 +00:00
|
|
|
break;
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
case 2: // auto hide
|
2002-04-03 12:08:54 +00:00
|
|
|
{
|
2002-05-08 14:12:28 +00:00
|
|
|
bool change = (slit.doAutoHide() ? false : true);
|
|
|
|
slit.do_auto_hide = change;
|
|
|
|
screen()->saveSlitAutoHide(change);
|
2002-04-03 12:08:54 +00:00
|
|
|
setItemSelected(3, change);
|
|
|
|
break;
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
2002-05-08 14:12:28 +00:00
|
|
|
//save the new configuration
|
|
|
|
Fluxbox::instance()->save_rc();
|
|
|
|
update();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Slitmenu::internal_hide(void) {
|
|
|
|
Basemenu::internal_hide();
|
2002-05-08 14:12:28 +00:00
|
|
|
if (slit.doAutoHide())
|
|
|
|
slit.timeout();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Slitmenu::reconfigure(void) {
|
|
|
|
directionmenu->reconfigure();
|
|
|
|
placementmenu->reconfigure();
|
2002-03-19 14:30:43 +00:00
|
|
|
#ifdef XINERAMA
|
2002-05-08 14:12:28 +00:00
|
|
|
if (screen()->hasXinerama()) {
|
2002-03-19 14:30:43 +00:00
|
|
|
headmenu->reconfigure();
|
|
|
|
}
|
|
|
|
#endif // XINERAMA
|
2002-05-08 14:12:28 +00:00
|
|
|
setItemSelected(2, slit.isOnTop());
|
|
|
|
setItemSelected(3, slit.doAutoHide());
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
Basemenu::reconfigure();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
Slitmenu::Directionmenu::Directionmenu(Slitmenu *sm) : Basemenu(sm->screen()),
|
|
|
|
slitmenu(sm) {
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
I18n *i18n = I18n::instance();
|
2002-04-04 11:28:19 +00:00
|
|
|
using namespace FBNLS;
|
2001-12-11 20:47:02 +00:00
|
|
|
setLabel(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
SlitSet, SlitSlitDirection,
|
|
|
|
"Slit Direction"));
|
2001-12-11 20:47:02 +00:00
|
|
|
setInternalMenu();
|
|
|
|
|
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonDirectionHoriz,
|
|
|
|
"Horizontal"),
|
2002-01-11 10:21:44 +00:00
|
|
|
Slit::HORIZONTAL);
|
2001-12-11 20:47:02 +00:00
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonDirectionVert,
|
|
|
|
"Vertical"),
|
2002-01-11 10:21:44 +00:00
|
|
|
Slit::VERTICAL);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
update();
|
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
if (screen()->getSlitDirection() == Slit::HORIZONTAL)
|
2002-04-03 12:08:54 +00:00
|
|
|
setItemSelected(0, true);
|
2001-12-11 20:47:02 +00:00
|
|
|
else
|
2002-04-03 12:08:54 +00:00
|
|
|
setItemSelected(1, true);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-04-03 12:08:54 +00:00
|
|
|
void Slitmenu::Directionmenu::itemSelected(int button, unsigned int index) {
|
2001-12-11 20:47:02 +00:00
|
|
|
if (button == 1) {
|
|
|
|
BasemenuItem *item = find(index);
|
|
|
|
if (! item) return;
|
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
screen()->saveSlitDirection(item->function());
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-01-11 10:21:44 +00:00
|
|
|
if (item->function() == Slit::HORIZONTAL) {
|
2002-04-03 12:08:54 +00:00
|
|
|
setItemSelected(0, true);
|
|
|
|
setItemSelected(1, false);
|
2001-12-11 20:47:02 +00:00
|
|
|
} else {
|
2002-04-03 12:08:54 +00:00
|
|
|
setItemSelected(0, false);
|
|
|
|
setItemSelected(1, true);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
2002-05-08 14:12:28 +00:00
|
|
|
Fluxbox::instance()->save_rc();
|
|
|
|
hide();
|
|
|
|
slitmenu->slit.reconfigure();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
Slitmenu::Placementmenu::Placementmenu(Slitmenu *sm) : Basemenu(sm->screen()),
|
|
|
|
slitmenu(sm) {
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
I18n *i18n = I18n::instance();
|
2002-04-04 11:28:19 +00:00
|
|
|
using namespace FBNLS;
|
2001-12-11 20:47:02 +00:00
|
|
|
setLabel(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
SlitSet, SlitSlitPlacement,
|
|
|
|
"Slit Placement"));
|
2001-12-11 20:47:02 +00:00
|
|
|
setMinimumSublevels(3);
|
|
|
|
setInternalMenu();
|
|
|
|
|
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonPlacementTopLeft,
|
|
|
|
"Top Left"),
|
2002-01-11 10:21:44 +00:00
|
|
|
Slit::TOPLEFT);
|
2001-12-11 20:47:02 +00:00
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonPlacementCenterLeft,
|
|
|
|
"Center Left"),
|
2002-01-11 10:21:44 +00:00
|
|
|
Slit::CENTERLEFT);
|
2001-12-11 20:47:02 +00:00
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonPlacementBottomLeft,
|
|
|
|
"Bottom Left"),
|
2002-01-11 10:21:44 +00:00
|
|
|
Slit::BOTTOMLEFT);
|
2001-12-11 20:47:02 +00:00
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonPlacementTopCenter,
|
|
|
|
"Top Center"),
|
2002-01-11 10:21:44 +00:00
|
|
|
Slit::TOPCENTER);
|
2001-12-11 20:47:02 +00:00
|
|
|
insert("");
|
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonPlacementBottomCenter,
|
|
|
|
"Bottom Center"),
|
2002-01-11 10:21:44 +00:00
|
|
|
Slit::BOTTOMCENTER);
|
2001-12-11 20:47:02 +00:00
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonPlacementTopRight,
|
|
|
|
"Top Right"),
|
2002-01-11 10:21:44 +00:00
|
|
|
Slit::TOPRIGHT);
|
2001-12-11 20:47:02 +00:00
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonPlacementCenterRight,
|
|
|
|
"Center Right"),
|
2002-01-11 10:21:44 +00:00
|
|
|
Slit::CENTERRIGHT);
|
2001-12-11 20:47:02 +00:00
|
|
|
insert(i18n->getMessage(
|
2002-04-04 11:28:19 +00:00
|
|
|
CommonSet, CommonPlacementBottomRight,
|
|
|
|
"Bottom Right"),
|
2002-01-11 10:21:44 +00:00
|
|
|
Slit::BOTTOMRIGHT);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-04-03 12:08:54 +00:00
|
|
|
void Slitmenu::Placementmenu::itemSelected(int button, unsigned int index) {
|
2001-12-11 20:47:02 +00:00
|
|
|
if (button == 1) {
|
|
|
|
BasemenuItem *item = find(index);
|
|
|
|
if (! item) return;
|
|
|
|
|
|
|
|
if (item->function()) {
|
2002-05-08 14:12:28 +00:00
|
|
|
screen()->saveSlitPlacement(item->function());
|
2001-12-11 20:47:02 +00:00
|
|
|
hide();
|
2002-05-08 14:12:28 +00:00
|
|
|
slitmenu->slit.reconfigure();
|
|
|
|
Fluxbox::instance()->save_rc();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-19 14:30:43 +00:00
|
|
|
#ifdef XINERAMA
|
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
Slitmenu::Headmenu::Headmenu(Slitmenu *sm): Basemenu(sm->screen()),
|
|
|
|
slitmenu(sm) {
|
|
|
|
|
2002-03-19 14:30:43 +00:00
|
|
|
I18n *i18n = I18n::instance();
|
|
|
|
|
|
|
|
setLabel(i18n->getMessage(0, 0, "Place on Head")); //TODO: NLS
|
|
|
|
setInternalMenu();
|
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
int numHeads = screen()->getNumHeads();
|
2002-03-19 14:30:43 +00:00
|
|
|
// fill menu with head entries
|
|
|
|
for (int i = 0; i < numHeads; i++) {
|
|
|
|
char headName[32];
|
|
|
|
sprintf(headName, "Head %i", i+1); //TODO: NLS
|
|
|
|
insert(i18n->getMessage(0, 0, headName), i);
|
|
|
|
}
|
|
|
|
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2002-04-08 18:58:47 +00:00
|
|
|
void Slitmenu::Headmenu::itemSelected(int button, unsigned int index) {
|
2002-03-19 14:30:43 +00:00
|
|
|
if (button == 1) {
|
|
|
|
BasemenuItem *item = find(index);
|
|
|
|
if (! item)
|
|
|
|
return;
|
|
|
|
|
2002-05-08 14:12:28 +00:00
|
|
|
screen()->saveSlitOnHead(item->function());
|
2002-03-19 14:30:43 +00:00
|
|
|
hide();
|
2002-05-08 14:12:28 +00:00
|
|
|
slitmenu->slit.reconfigure();
|
|
|
|
Fluxbox::instance()->save_rc();
|
2002-03-19 14:30:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // XINERAMA
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-29 06:21:59 +00:00
|
|
|
Slit::SlitClient::SlitClient(const char *name)
|
|
|
|
{
|
|
|
|
initialize();
|
|
|
|
match_name = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Slit::SlitClient::SlitClient(BScreen *screen, Window w)
|
|
|
|
{
|
|
|
|
initialize(screen, w);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Slit::SlitClient::initialize(BScreen *screen, Window w) {
|
|
|
|
client_window = w;
|
|
|
|
window = icon_window = None;
|
|
|
|
x = y = 0;
|
|
|
|
width = height = 0;
|
|
|
|
if (match_name.size() == 0)
|
|
|
|
getWMName(screen, client_window, match_name);
|
|
|
|
}
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
#endif // SLIT
|