add back some xinerama support (toolbar, slit (+menu), screen)
This commit is contained in:
parent
68e9677bbb
commit
cc9c7960c1
7 changed files with 336 additions and 22 deletions
|
@ -1,6 +1,8 @@
|
|||
(Format: Year/Month/Day)
|
||||
Changes for 0.9.3:
|
||||
*03/05/19:
|
||||
* Add back some Xinerama support (still need placement + maximise) (Simon)
|
||||
Screen.hh/cc Toolbar.cc Slit.cc Xinerama.hh
|
||||
* Fix bsetroot segfault (Simon)
|
||||
FbWindow.cc
|
||||
*03/05/18:
|
||||
|
|
2
RoadMap
2
RoadMap
|
@ -117,7 +117,7 @@ Bugfixes/lower priority:
|
|||
Release: 0.9.3
|
||||
Approx Date: 26 May, 2003
|
||||
Major Features:
|
||||
- Xinerama (Simon)
|
||||
= Xinerama (Simon)
|
||||
* XRandr (Henrik)
|
||||
Minor Features:
|
||||
- Add some sort of program launch function (Simon)
|
||||
|
|
132
src/Screen.cc
132
src/Screen.cc
|
@ -22,7 +22,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// $Id: Screen.cc,v 1.171 2003/05/18 22:01:14 fluxgen Exp $
|
||||
// $Id: Screen.cc,v 1.172 2003/05/19 14:26:29 rathnor Exp $
|
||||
|
||||
|
||||
#include "Screen.hh"
|
||||
|
@ -114,6 +114,12 @@
|
|||
#include <X11/Xatom.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#ifdef XINERAMA
|
||||
extern "C" {
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
}
|
||||
#endif // XINERAMA
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
@ -480,13 +486,14 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
|
|||
toolbar_on_head(rm, 0, scrname+".toolbar.onhead", altscrname+".Toolbar.onHead"),
|
||||
toolbar_placement(rm, Toolbar::BOTTOMCENTER,
|
||||
scrname+".toolbar.placement", altscrname+".Toolbar.Placement"),
|
||||
slit_auto_hide(rm, false,
|
||||
scrname+".slit.autoHide", altscrname+".Slit.AutoHide"),
|
||||
slit_placement(rm, Slit::BOTTOMRIGHT,
|
||||
scrname+".slit.placement", altscrname+".Slit.Placement"),
|
||||
slit_direction(rm, Slit::VERTICAL,
|
||||
scrname+".slit.direction", altscrname+".Slit.Direction"),
|
||||
slit_alpha(rm, 255, scrname+".slit.alpha", altscrname+".Slit.Alpha") {
|
||||
slit_auto_hide(rm, false,
|
||||
scrname+".slit.autoHide", altscrname+".Slit.AutoHide"),
|
||||
slit_placement(rm, Slit::BOTTOMRIGHT,
|
||||
scrname+".slit.placement", altscrname+".Slit.Placement"),
|
||||
slit_direction(rm, Slit::VERTICAL,
|
||||
scrname+".slit.direction", altscrname+".Slit.Direction"),
|
||||
slit_alpha(rm, 255, scrname+".slit.alpha", altscrname+".Slit.Alpha"),
|
||||
slit_on_head(rm, 0, scrname+".slit.onhead", altscrname+".Slit.onHead") {
|
||||
|
||||
};
|
||||
|
||||
|
@ -516,6 +523,10 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
|||
|
||||
Display *disp = FbTk::App::instance()->display();
|
||||
|
||||
#ifdef XINERAMA
|
||||
initXinerama(disp);
|
||||
#endif // XINERAMA
|
||||
|
||||
event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
|
||||
SubstructureRedirectMask | KeyPressMask | KeyReleaseMask |
|
||||
ButtonPressMask | ButtonReleaseMask| SubstructureNotifyMask;
|
||||
|
@ -761,6 +772,12 @@ BScreen::~BScreen() {
|
|||
}
|
||||
|
||||
netizenList.clear();
|
||||
|
||||
#ifdef XINERAMA
|
||||
if (hasXinerama() && m_xinerama_headinfo) {
|
||||
delete [] m_xinerama_headinfo;
|
||||
}
|
||||
#endif // XINERAMA
|
||||
}
|
||||
|
||||
const FbTk::Menu &BScreen::toolbarModemenu() const {
|
||||
|
@ -2524,3 +2541,102 @@ void BScreen::updateSize() {
|
|||
//!! TODO: should we re-maximize the maximized windows?
|
||||
|
||||
}
|
||||
|
||||
#ifdef XINERAMA
|
||||
|
||||
void BScreen::initXinerama(Display *display) {
|
||||
if (!XineramaIsActive(display)) {
|
||||
m_xinerama_avail = false;
|
||||
m_xinerama_headinfo = 0;
|
||||
return;
|
||||
}
|
||||
m_xinerama_avail = true;
|
||||
|
||||
XineramaScreenInfo *screen_info;
|
||||
int number;
|
||||
screen_info = XineramaQueryScreens(display, &number);
|
||||
m_xinerama_headinfo = new XineramaHeadInfo[number];
|
||||
m_xinerama_num_heads = number;
|
||||
for (int i=0; i < number; i++) {
|
||||
m_xinerama_headinfo[i].x = screen_info[i].x_org;
|
||||
m_xinerama_headinfo[i].y = screen_info[i].y_org;
|
||||
m_xinerama_headinfo[i].width = screen_info[i].width;
|
||||
m_xinerama_headinfo[i].height = screen_info[i].height;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int BScreen::getHead(int x, int y) const {
|
||||
if (!hasXinerama()) return 0;
|
||||
|
||||
for (int i=0; i < m_xinerama_num_heads; i++) {
|
||||
if (x >= m_xinerama_headinfo[i].x &&
|
||||
x < (m_xinerama_headinfo[i].x + m_xinerama_headinfo[i].width) &&
|
||||
y >= m_xinerama_headinfo[i].y &&
|
||||
y < (m_xinerama_headinfo[i].y + m_xinerama_headinfo[i].height)) {
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BScreen::getCurrHead() const {
|
||||
if (!hasXinerama()) return 0;
|
||||
int root_x, root_y, ignore_i;
|
||||
|
||||
unsigned int ignore_ui;
|
||||
|
||||
Window ignore_w;
|
||||
|
||||
XQueryPointer(FbTk::App::instance()->display(),
|
||||
rootWindow().window(), &ignore_w,
|
||||
&ignore_w, &root_x, &root_y,
|
||||
&ignore_i, &ignore_i, &ignore_ui);
|
||||
return getHead(root_x, root_y);
|
||||
|
||||
}
|
||||
|
||||
int BScreen::getHeadX(int head) const {
|
||||
if (head == 0 || head > m_xinerama_num_heads) return 0;
|
||||
return m_xinerama_headinfo[head-1].x;
|
||||
}
|
||||
|
||||
int BScreen::getHeadY(int head) const {
|
||||
if (head == 0 || head > m_xinerama_num_heads) return 0;
|
||||
return m_xinerama_headinfo[head-1].y;
|
||||
}
|
||||
|
||||
int BScreen::getHeadWidth(int head) const {
|
||||
if (head == 0 || head > m_xinerama_num_heads) return width();
|
||||
return m_xinerama_headinfo[head-1].width;
|
||||
}
|
||||
|
||||
int BScreen::getHeadHeight(int head) const {
|
||||
if (head == 0 || head > m_xinerama_num_heads) return height();
|
||||
return m_xinerama_headinfo[head-1].height;
|
||||
}
|
||||
|
||||
template <>
|
||||
int BScreen::getOnHead<Toolbar>(Toolbar &tbar) {
|
||||
return getToolbarOnHead();
|
||||
}
|
||||
|
||||
template <>
|
||||
void BScreen::setOnHead<Toolbar>(Toolbar &tbar, int head) {
|
||||
saveToolbarOnHead(head);
|
||||
tbar.reconfigure();
|
||||
}
|
||||
|
||||
template <>
|
||||
int BScreen::getOnHead<Slit>(Slit &tbar) {
|
||||
return getSlitOnHead();
|
||||
}
|
||||
|
||||
template <>
|
||||
void BScreen::setOnHead<Slit>(Slit &slit, int head) {
|
||||
saveSlitOnHead(head);
|
||||
slit.reconfigure();
|
||||
}
|
||||
|
||||
#endif // XINERAMA
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// $Id: Screen.hh,v 1.99 2003/05/18 22:00:04 fluxgen Exp $
|
||||
// $Id: Screen.hh,v 1.100 2003/05/19 14:26:30 rathnor Exp $
|
||||
|
||||
#ifndef SCREEN_HH
|
||||
#define SCREEN_HH
|
||||
|
@ -116,8 +116,8 @@ public:
|
|||
inline void saveSlitDirection(Slit::Direction d) { resource.slit_direction = d; }
|
||||
inline void saveSlitAutoHide(bool t) { resource.slit_auto_hide = t; }
|
||||
|
||||
inline unsigned int getSlitOnHead() const { return resource.slit_on_head; }
|
||||
inline void saveSlitOnHead(unsigned int h) { resource.slit_on_head = h; }
|
||||
inline int getSlitOnHead() const { return *resource.slit_on_head; }
|
||||
inline void saveSlitOnHead(int h) { *resource.slit_on_head = h; }
|
||||
|
||||
inline const Toolbar *toolbar() const { return m_toolbarhandler->getToolbar(); }
|
||||
inline Toolbar *toolbar() { return m_toolbarhandler->getToolbar(); }
|
||||
|
@ -296,6 +296,29 @@ public:
|
|||
/// (and maximized windows?)
|
||||
void updateSize();
|
||||
|
||||
#ifdef XINERAMA
|
||||
// Xinerama-related functions
|
||||
inline bool hasXinerama() const { return m_xinerama_avail; }
|
||||
inline int numHeads() const { return m_xinerama_num_heads; }
|
||||
|
||||
void initXinerama(Display *display);
|
||||
|
||||
int getHead(int x, int y) const;
|
||||
int getCurrHead() const;
|
||||
int getHeadX(int head) const;
|
||||
int getHeadY(int head) const;
|
||||
int getHeadWidth(int head) const;
|
||||
int getHeadHeight(int head) const;
|
||||
|
||||
// magic to allow us to have "on head" placement without
|
||||
// the object really knowing about it.
|
||||
template <typename OnHeadObject>
|
||||
int getOnHead(OnHeadObject &obj);
|
||||
|
||||
template <typename OnHeadObject>
|
||||
void setOnHead(OnHeadObject &obj, int head);
|
||||
#endif // XINERAMA
|
||||
|
||||
// notify netizens
|
||||
void updateNetizenCurrentWorkspace();
|
||||
void updateNetizenWorkspaceCount();
|
||||
|
@ -412,9 +435,7 @@ private:
|
|||
FbTk::Resource<bool> slit_auto_hide;
|
||||
FbTk::Resource<Slit::Placement> slit_placement;
|
||||
FbTk::Resource<Slit::Direction> slit_direction;
|
||||
FbTk::Resource<int> slit_alpha;
|
||||
|
||||
unsigned int slit_on_head;
|
||||
FbTk::Resource<int> slit_alpha, slit_on_head;
|
||||
|
||||
std::string strftime_format;
|
||||
|
||||
|
@ -425,6 +446,21 @@ private:
|
|||
} resource;
|
||||
|
||||
std::auto_ptr<ToolbarHandler> m_toolbarhandler;
|
||||
|
||||
#ifdef XINERAMA
|
||||
// Xinerama related private data
|
||||
bool m_xinerama_avail;
|
||||
int m_xinerama_num_heads;
|
||||
|
||||
int m_xinerama_center_x, m_xinerama_center_y;
|
||||
|
||||
struct XineramaHeadInfo {
|
||||
int x, y, width, height;
|
||||
} *m_xinerama_headinfo;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
34
src/Slit.cc
34
src/Slit.cc
|
@ -22,7 +22,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// $Id: Slit.cc,v 1.55 2003/05/17 11:00:50 fluxgen Exp $
|
||||
// $Id: Slit.cc,v 1.56 2003/05/19 14:26:30 rathnor Exp $
|
||||
|
||||
#include "Slit.hh"
|
||||
|
||||
|
@ -52,6 +52,10 @@
|
|||
#include "Transparent.hh"
|
||||
#include "IntResMenuItem.hh"
|
||||
|
||||
#ifdef XINERAMA
|
||||
#include "Xinerama.hh"
|
||||
#endif // XINERAMA
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
@ -790,8 +794,20 @@ void Slit::reposition() {
|
|||
head_w,
|
||||
head_h;
|
||||
|
||||
head_w = screen().width();
|
||||
head_h = screen().height();
|
||||
#ifdef XINERAMA
|
||||
if (screen().hasXinerama()) {
|
||||
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
|
||||
#endif // XINERAMA
|
||||
{
|
||||
head_w = screen().width();
|
||||
head_h = screen().height();
|
||||
}
|
||||
|
||||
int border_width = screen().rootTheme().borderWidth();
|
||||
int bevel_width = screen().rootTheme().bevelWidth();
|
||||
|
||||
|
@ -1206,6 +1222,18 @@ void Slit::setupMenu() {
|
|||
|
||||
m_slitmenu.insert("Layer...", m_layermenu.get());
|
||||
|
||||
#ifdef XINERAMA
|
||||
if (screen().hasXinerama()) {
|
||||
m_slitmenu.insert("On Head...", new XineramaHeadMenu<Slit>(
|
||||
*screen().menuTheme(),
|
||||
screen(),
|
||||
screen().imageControl(),
|
||||
*screen().layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
|
||||
this
|
||||
));
|
||||
}
|
||||
|
||||
#endif //XINERAMA
|
||||
m_slitmenu.insert(new BoolMenuItem(i18n->getMessage(
|
||||
CommonSet, CommonAutoHide,
|
||||
"Auto hide"),
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// $Id: Toolbar.cc,v 1.84 2003/05/17 11:30:59 fluxgen Exp $
|
||||
// $Id: Toolbar.cc,v 1.85 2003/05/19 14:26:30 rathnor Exp $
|
||||
|
||||
#include "Toolbar.hh"
|
||||
|
||||
|
@ -43,6 +43,10 @@
|
|||
#include "BoolMenuItem.hh"
|
||||
#include "FbWinFrameTheme.hh"
|
||||
|
||||
#ifdef XINERAMA
|
||||
#include "Xinerama.hh"
|
||||
#endif XINERAMA
|
||||
|
||||
// use GNU extensions
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
@ -134,6 +138,18 @@ void setupMenus(Toolbar &tbar) {
|
|||
menu.setInternalMenu();
|
||||
|
||||
menu.insert("Layer...", &tbar.layermenu());
|
||||
#ifdef XINERAMA
|
||||
if (tbar.screen().hasXinerama()) {
|
||||
menu.insert("On Head...", new XineramaHeadMenu<Toolbar>(
|
||||
*tbar.screen().menuTheme(),
|
||||
tbar.screen(),
|
||||
tbar.screen().imageControl(),
|
||||
*tbar.screen().layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
|
||||
&tbar
|
||||
));
|
||||
}
|
||||
|
||||
#endif //XINERAMA
|
||||
|
||||
// setup items in placement menu
|
||||
struct {
|
||||
|
@ -1091,10 +1107,21 @@ void Toolbar::setPlacement(Toolbar::Placement where) {
|
|||
head_w,
|
||||
head_h;
|
||||
|
||||
m_place = where;
|
||||
#ifdef XINERAMA
|
||||
if (screen().hasXinerama()) {
|
||||
int head = screen().getToolbarOnHead();
|
||||
head_x = screen().getHeadX(head);
|
||||
head_y = screen().getHeadY(head);
|
||||
head_w = screen().getHeadWidth(head);
|
||||
head_h = screen().getHeadHeight(head);
|
||||
} else
|
||||
#endif // XINERAMA
|
||||
{
|
||||
head_w = screen().width();
|
||||
head_h = screen().height();
|
||||
}
|
||||
|
||||
head_w = screen().width();
|
||||
head_h = screen().height();
|
||||
m_place = where;
|
||||
|
||||
frame.width = head_w * screen().getToolbarWidthPercent() / 100;
|
||||
frame.height = m_theme.font().height();
|
||||
|
|
105
src/Xinerama.hh
Normal file
105
src/Xinerama.hh
Normal file
|
@ -0,0 +1,105 @@
|
|||
// Xinerama.hh for Fluxbox - helpful tools for multiple heads
|
||||
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
|
||||
// and Simon Bowden (rathnor at users.sourceforge.net)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// $Id: Xinerama.hh,v 1.1 2003/05/19 14:26:30 rathnor Exp $
|
||||
|
||||
#ifndef XINERAMA_HH
|
||||
#define XINERAMA_HH
|
||||
|
||||
#include "MenuItem.hh"
|
||||
#include "FbMenu.hh"
|
||||
#include "FbCommands.hh"
|
||||
#include "RefCount.hh"
|
||||
#include "SimpleCommand.hh"
|
||||
|
||||
#include "fluxbox.hh"
|
||||
|
||||
// provides a generic way for giving an object a xinerama head menu
|
||||
// The object must have two functions:
|
||||
// int getOnHead(), and
|
||||
// void setOnHead(int)
|
||||
|
||||
/// this class holds the xinerama items
|
||||
template <typename ItemType>
|
||||
class XineramaHeadMenuItem : public FbTk::MenuItem {
|
||||
public:
|
||||
XineramaHeadMenuItem(const char *label, ItemType *object, int headnum,
|
||||
FbTk::RefCount<FbTk::Command> &cmd):
|
||||
FbTk::MenuItem(label,cmd), m_object(object), m_headnum(headnum) {}
|
||||
XineramaHeadMenuItem(const char *label, ItemType *object, int headnum):
|
||||
FbTk::MenuItem(label), m_object(object), m_headnum(headnum) {}
|
||||
|
||||
bool isEnabled() const { return m_object->screen().getOnHead(*m_object) != m_headnum; } ;
|
||||
void click(int button, int time) {
|
||||
m_object->screen().setOnHead(*m_object, m_headnum);
|
||||
FbTk::MenuItem::click(button, time);
|
||||
}
|
||||
|
||||
private:
|
||||
ItemType *m_object;
|
||||
int m_headnum;
|
||||
};
|
||||
|
||||
|
||||
/// Create a xinerama menu
|
||||
template <typename ItemType>
|
||||
class XineramaHeadMenu : public FbMenu {
|
||||
public:
|
||||
XineramaHeadMenu(FbTk::MenuTheme &tm, BScreen &screen, FbTk::ImageControl &imgctrl,
|
||||
FbTk::XLayer &layer, ItemType *item);
|
||||
|
||||
private:
|
||||
ItemType *m_object;
|
||||
};
|
||||
|
||||
|
||||
template <typename ItemType>
|
||||
XineramaHeadMenu<ItemType>::XineramaHeadMenu(FbTk::MenuTheme &tm, BScreen &screen, FbTk::ImageControl &imgctrl,
|
||||
FbTk::XLayer &layer, ItemType *item):
|
||||
FbMenu(tm, screen.screenNumber(), imgctrl, layer),
|
||||
m_object(item)
|
||||
{
|
||||
|
||||
FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
|
||||
*Fluxbox::instance(),
|
||||
&Fluxbox::save_rc));
|
||||
char tname[128];
|
||||
for (int i=1; i <= screen.numHeads(); ++i) {
|
||||
// TODO: nls
|
||||
/*
|
||||
sprintf(tname, I18n::instance()->
|
||||
getMessage(
|
||||
FBNLS::ScreenSet,
|
||||
FBNLS::XineramaDefaultHeadFormat,
|
||||
"Head %d"), i); //m_id starts at 0
|
||||
*/
|
||||
sprintf(tname, "Head %d", i);
|
||||
insert(new XineramaHeadMenuItem<ItemType>(
|
||||
tname, m_object, i, saverc_cmd));
|
||||
}
|
||||
// TODO: nls
|
||||
insert(new XineramaHeadMenuItem<ItemType>(
|
||||
"All Heads", m_object, 0, saverc_cmd));
|
||||
update();
|
||||
}
|
||||
|
||||
#endif // XINERAMA_HH
|
Loading…
Reference in a new issue