Merge branch 'xinerama_randr'
This commit is contained in:
commit
880209a438
9 changed files with 122 additions and 23 deletions
|
@ -1,5 +1,10 @@
|
|||
(Format: Year/Month/Day)
|
||||
Changes for 1.0.1:
|
||||
*08/01/27:
|
||||
* Reload the Xinerama layout on RandR signal (Tomas)
|
||||
Screen.cc/hh
|
||||
* Move windows out of inactive heads upon Xinerama layout change (Tomas)
|
||||
Screen.cc/hh
|
||||
*07/12/28:
|
||||
* Added new key command :Delay {<command>} [<int>], which runs the command
|
||||
after a delay of <int> microseconds (default is 200 milliseconds) (Mark)
|
||||
|
|
|
@ -360,6 +360,12 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
|||
Display *disp = m_root_window.display();
|
||||
Fluxbox *fluxbox = Fluxbox::instance();
|
||||
|
||||
// TODO fluxgen: check if this is the right place (it was not -lis)
|
||||
//
|
||||
// Create the first one, initXinerama will expand this if needed.
|
||||
m_head_areas.resize(1);
|
||||
m_head_areas[0] = new HeadArea();
|
||||
|
||||
initXinerama();
|
||||
|
||||
// setup error handler to catch "screen already managed by other wm"
|
||||
|
@ -402,9 +408,6 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
|||
XFree(ret_prop);
|
||||
}
|
||||
|
||||
// TODO fluxgen: check if this is the right place
|
||||
m_head_areas = new HeadArea[numHeads() ? numHeads() : 1];
|
||||
|
||||
#ifdef HAVE_RANDR
|
||||
// setup RANDR for this screens root window
|
||||
// we need to determine if we should use old randr select input function or not
|
||||
|
@ -600,7 +603,8 @@ BScreen::~BScreen() {
|
|||
m_slit.reset(0);
|
||||
|
||||
// TODO fluxgen: check if this is the right place
|
||||
delete [] m_head_areas;
|
||||
for (int i = 0; i < m_head_areas.size(); i++)
|
||||
delete m_head_areas[i];
|
||||
|
||||
delete m_focus_control;
|
||||
delete m_placement_strategy;
|
||||
|
@ -722,7 +726,12 @@ unsigned int BScreen::currentWorkspaceID() const {
|
|||
}
|
||||
|
||||
const Strut* BScreen::availableWorkspaceArea(int head) const {
|
||||
return m_head_areas[head ? head-1 : 0].availableWorkspaceArea();
|
||||
if (head > numHeads()) {
|
||||
/* May this ever happen? */
|
||||
static Strut whole(-1 /* should never be used */, 0, width(), 0, height());
|
||||
return &whole;
|
||||
}
|
||||
return m_head_areas[head ? head-1 : 0]->availableWorkspaceArea();
|
||||
}
|
||||
|
||||
unsigned int BScreen::maxLeft(int head) const {
|
||||
|
@ -1412,7 +1421,7 @@ Strut *BScreen::requestStrut(int head, int left, int right, int top, int bottom)
|
|||
|
||||
Strut* next = 0;
|
||||
for (int i = begin; i != end; i++) {
|
||||
next = m_head_areas[i].requestStrut(i+1, left, right, top, bottom, next);
|
||||
next = m_head_areas[i]->requestStrut(i+1, left, right, top, bottom, next);
|
||||
}
|
||||
|
||||
return next;
|
||||
|
@ -1422,7 +1431,9 @@ void BScreen::clearStrut(Strut *str) {
|
|||
if (str->next())
|
||||
clearStrut(str->next());
|
||||
int head = str->head() ? str->head() - 1 : 0;
|
||||
m_head_areas[head].clearStrut(str);
|
||||
/* The number of heads may have changed, be careful. */
|
||||
if (head < numHeads())
|
||||
m_head_areas[head]->clearStrut(str);
|
||||
// str is invalid now
|
||||
}
|
||||
|
||||
|
@ -1431,7 +1442,7 @@ void BScreen::updateAvailableWorkspaceArea() {
|
|||
bool updated = false;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
updated = m_head_areas[i].updateAvailableWorkspaceArea() || updated;
|
||||
updated = m_head_areas[i]->updateAvailableWorkspaceArea() || updated;
|
||||
}
|
||||
|
||||
if (updated)
|
||||
|
@ -1886,6 +1897,9 @@ void BScreen::renderPosWindow() {
|
|||
}
|
||||
|
||||
void BScreen::updateSize() {
|
||||
// update xinerama layout
|
||||
initXinerama();
|
||||
|
||||
// force update geometry
|
||||
rootWindow().updateGeometry();
|
||||
|
||||
|
@ -1895,6 +1909,9 @@ void BScreen::updateSize() {
|
|||
// send resize notify
|
||||
m_resize_sig.notify();
|
||||
m_workspace_area_sig.notify();
|
||||
|
||||
// move windows out of inactive heads
|
||||
clearHeads();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1941,10 +1958,13 @@ void BScreen::initXinerama() {
|
|||
Display *display = FbTk::App::instance()->display();
|
||||
|
||||
if (!XineramaIsActive(display)) {
|
||||
notactive:
|
||||
#ifdef DEBUG
|
||||
cerr<<"BScreen::initXinerama(): dont have Xinerama"<<endl;
|
||||
#endif // DEBUG
|
||||
m_xinerama_avail = false;
|
||||
if (m_xinerama_headinfo)
|
||||
delete [] m_xinerama_headinfo;
|
||||
m_xinerama_headinfo = 0;
|
||||
m_xinerama_num_heads = 0;
|
||||
return;
|
||||
|
@ -1957,6 +1977,19 @@ void BScreen::initXinerama() {
|
|||
XineramaScreenInfo *screen_info;
|
||||
int number;
|
||||
screen_info = XineramaQueryScreens(display, &number);
|
||||
|
||||
/* The call may have actually failed. If this is the first time we init
|
||||
* Xinerama, fall back to turning it off. If not, pretend nothing
|
||||
* happened -- another event will tell us and it will work then. */
|
||||
if (!screen_info) {
|
||||
if (m_xinerama_headinfo)
|
||||
return;
|
||||
else
|
||||
goto notactive;
|
||||
}
|
||||
|
||||
if (m_xinerama_headinfo)
|
||||
delete [] m_xinerama_headinfo;
|
||||
m_xinerama_headinfo = new XineramaHeadInfo[number];
|
||||
m_xinerama_num_heads = number;
|
||||
for (int i=0; i < number; i++) {
|
||||
|
@ -1970,6 +2003,18 @@ void BScreen::initXinerama() {
|
|||
cerr<<"BScreen::initXinerama(): number of heads ="<<number<<endl;
|
||||
#endif // DEBUG
|
||||
|
||||
/* Reallocate to the new number of heads. */
|
||||
int ha_num = numHeads() ? numHeads() : 1, ha_oldnum = m_head_areas.size();
|
||||
if (ha_num > ha_oldnum) {
|
||||
m_head_areas.resize(ha_num);
|
||||
for (int i = ha_oldnum; i < ha_num; i++)
|
||||
m_head_areas[i] = new HeadArea();
|
||||
} else if (ha_num < ha_oldnum) {
|
||||
for (int i = ha_num; i < ha_oldnum; i++)
|
||||
delete m_head_areas[i];
|
||||
m_head_areas.resize(ha_num);
|
||||
}
|
||||
|
||||
#else // XINERAMA
|
||||
// no xinerama
|
||||
m_xinerama_avail = false;
|
||||
|
@ -1978,6 +2023,22 @@ void BScreen::initXinerama() {
|
|||
|
||||
}
|
||||
|
||||
/* Move windows out of inactive heads */
|
||||
void BScreen::clearHeads() {
|
||||
if (!hasXinerama()) return;
|
||||
|
||||
for (Workspaces::iterator i = m_workspaces_list.begin();
|
||||
i != m_workspaces_list.end(); i++) {
|
||||
for (Workspace::Windows::iterator win = (*i)->windowList().begin();
|
||||
win != (*i)->windowList().end(); win++) {
|
||||
if (getHead((*win)->fbWindow()) == 0) {
|
||||
// first head is a safe bet here
|
||||
(*win)->placeWindow(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int BScreen::getHead(int x, int y) const {
|
||||
if (!hasXinerama()) return 0;
|
||||
#ifdef XINERAMA
|
||||
|
|
|
@ -406,6 +406,7 @@ public:
|
|||
int numHeads() const { return m_xinerama_num_heads; }
|
||||
|
||||
void initXinerama();
|
||||
void clearHeads();
|
||||
/**
|
||||
* Determines head number for a position
|
||||
* @param x position in pixels on the screen
|
||||
|
@ -590,7 +591,7 @@ private:
|
|||
int m_xinerama_num_heads;
|
||||
int m_xinerama_center_x, m_xinerama_center_y;
|
||||
|
||||
HeadArea *m_head_areas;
|
||||
std::vector<HeadArea *> m_head_areas;
|
||||
|
||||
struct XineramaHeadInfo {
|
||||
int x, y, width, height;
|
||||
|
|
15
src/Slit.cc
15
src/Slit.cc
|
@ -48,10 +48,6 @@
|
|||
#include "RootTheme.hh"
|
||||
#include "FbMenu.hh"
|
||||
|
||||
#ifdef XINERAMA
|
||||
#include "Xinerama.hh"
|
||||
#endif // XINERAMA
|
||||
|
||||
#include "SlitTheme.hh"
|
||||
#include "SlitClient.hh"
|
||||
#include "Xutil.hh"
|
||||
|
@ -270,6 +266,9 @@ Slit::Slit(BScreen &scr, FbTk::XLayer &layer, const char *filename)
|
|||
m_slitmenu(scr.menuTheme(),
|
||||
scr.imageControl(),
|
||||
*scr.layerManager().getLayer(Layer::MENU)),
|
||||
#ifdef XINERAMA
|
||||
m_xineramaheadmenu(0),
|
||||
#endif // XINERAMA
|
||||
frame(scr.rootWindow()),
|
||||
//For KDE dock applets
|
||||
m_kwm1_dockwindow(XInternAtom(FbTk::App::instance()->display(),
|
||||
|
@ -482,8 +481,7 @@ void Slit::addClient(Window w) {
|
|||
if (wmhints != 0) {
|
||||
if ((wmhints->flags & IconWindowHint) &&
|
||||
(wmhints->icon_window != None)) {
|
||||
XMoveWindow(disp, client->clientWindow(), screen().width() + 10,
|
||||
screen().height() + 10);
|
||||
XMoveWindow(disp, client->clientWindow(), -100, -100);
|
||||
XMapWindow(disp, client->clientWindow());
|
||||
client->setIconWindow(wmhints->icon_window);
|
||||
client->setWindow(client->iconWindow());
|
||||
|
@ -1113,6 +1111,10 @@ void Slit::exposeEvent(XExposeEvent &ev) {
|
|||
|
||||
void Slit::update(FbTk::Subject *subj) {
|
||||
reconfigure();
|
||||
#ifdef XINERAMA
|
||||
if (subj == &m_screen.resizeSig() && m_xineramaheadmenu)
|
||||
m_xineramaheadmenu->reloadHeads();
|
||||
#endif // XINERAMA
|
||||
}
|
||||
|
||||
void Slit::clearWindow() {
|
||||
|
@ -1254,6 +1256,7 @@ void Slit::setupMenu() {
|
|||
#ifdef XINERAMA
|
||||
if (screen().hasXinerama()) {
|
||||
m_slitmenu.insert(_FB_XTEXT(Menu, OnHead, "On Head...", "Title of On Head menu"),
|
||||
m_xineramaheadmenu =
|
||||
new XineramaHeadMenu<Slit>(
|
||||
screen().menuTheme(),
|
||||
screen(),
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#include "LayerMenu.hh"
|
||||
#include "Layer.hh"
|
||||
|
||||
#ifdef XINERAMA
|
||||
#include "Xinerama.hh"
|
||||
#endif // XINERAMA
|
||||
|
||||
#include "FbTk/Menu.hh"
|
||||
#include "FbTk/FbWindow.hh"
|
||||
#include "FbTk/Timer.hh"
|
||||
|
@ -144,6 +148,9 @@ private:
|
|||
SlitClients m_client_list;
|
||||
std::auto_ptr<LayerMenu> m_layermenu;
|
||||
FbMenu m_clientlist_menu, m_slitmenu;
|
||||
#ifdef XINERAMA
|
||||
XineramaHeadMenu<Slit> *m_xineramaheadmenu;
|
||||
#endif // XINERAMA
|
||||
std::string m_filename;
|
||||
|
||||
struct frame {
|
||||
|
|
|
@ -35,10 +35,6 @@
|
|||
#include "Screen.hh"
|
||||
#include "WindowCmd.hh"
|
||||
|
||||
#ifdef XINERAMA
|
||||
#include "Xinerama.hh"
|
||||
#endif // XINERAMA
|
||||
|
||||
#include "Strut.hh"
|
||||
#include "FbTk/CommandParser.hh"
|
||||
#include "Layer.hh"
|
||||
|
@ -216,6 +212,9 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width):
|
|||
m_toolbarmenu(scrn.menuTheme(),
|
||||
scrn.imageControl(),
|
||||
*scrn.layerManager().getLayer(Layer::MENU)),
|
||||
#ifdef XINERAMA
|
||||
m_xineramaheadmenu(0),
|
||||
#endif // XINERAMA
|
||||
m_theme(scrn.screenNumber()),
|
||||
m_tool_factory(scrn),
|
||||
m_strut(0),
|
||||
|
@ -629,6 +628,10 @@ void Toolbar::update(FbTk::Subject *subj) {
|
|||
else
|
||||
reconfigure();
|
||||
|
||||
#ifdef XINERAMA
|
||||
if (subj == &m_screen.resizeSig() && m_xineramaheadmenu)
|
||||
m_xineramaheadmenu->reloadHeads();
|
||||
#endif // XINERAMA
|
||||
}
|
||||
|
||||
void Toolbar::setPlacement(Toolbar::Placement where) {
|
||||
|
@ -872,6 +875,7 @@ void Toolbar::setupMenus(bool skip_new_placement) {
|
|||
#ifdef XINERAMA
|
||||
if (screen().hasXinerama()) {
|
||||
menu().insert(_FB_XTEXT(Menu, OnHead, "On Head...", "Title of On Head menu"),
|
||||
m_xineramaheadmenu =
|
||||
new XineramaHeadMenu<Toolbar>(screen().menuTheme(),
|
||||
screen(),
|
||||
screen().imageControl(),
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
#include "ToolTheme.hh"
|
||||
#include "Layer.hh"
|
||||
|
||||
#ifdef XINERAMA
|
||||
#include "Xinerama.hh"
|
||||
#endif // XINERAMA
|
||||
|
||||
#include "FbTk/Timer.hh"
|
||||
#include "FbTk/Resource.hh"
|
||||
#include "FbTk/Observer.hh"
|
||||
|
@ -159,6 +163,9 @@ private:
|
|||
FbTk::XLayerItem m_layeritem; ///< layer item, must be declared before layermenu
|
||||
LayerMenu m_layermenu;
|
||||
FbMenu m_placementmenu, m_toolbarmenu;
|
||||
#ifdef XINERAMA
|
||||
XineramaHeadMenu<Toolbar> *m_xineramaheadmenu;
|
||||
#endif // XINERAMA
|
||||
|
||||
|
||||
// themes
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "FbMenu.hh"
|
||||
#include "fluxbox.hh"
|
||||
#include "Screen.hh"
|
||||
|
||||
#include "FbTk/RefCount.hh"
|
||||
#include "FbTk/SimpleCommand.hh"
|
||||
|
@ -59,14 +60,16 @@ private:
|
|||
|
||||
/// Create a xinerama menu
|
||||
template <typename ItemType>
|
||||
class XineramaHeadMenu : public FbMenu {
|
||||
class XineramaHeadMenu : public ToggleMenu {
|
||||
public:
|
||||
XineramaHeadMenu(FbTk::ThemeProxy<FbTk::MenuTheme> &tm, BScreen &screen,
|
||||
FbTk::ImageControl &imgctrl, FbTk::XLayer &layer,
|
||||
ItemType &item, const FbTk::FbString & title = "");
|
||||
void reloadHeads();
|
||||
|
||||
private:
|
||||
ItemType &m_object;
|
||||
BScreen &m_screen;
|
||||
};
|
||||
|
||||
|
||||
|
@ -75,15 +78,22 @@ XineramaHeadMenu<ItemType>::XineramaHeadMenu(
|
|||
FbTk::ThemeProxy<FbTk::MenuTheme> &tm, BScreen &screen,
|
||||
FbTk::ImageControl &imgctrl, FbTk::XLayer &layer, ItemType &item,
|
||||
const FbTk::FbString & title):
|
||||
FbMenu(tm, imgctrl, layer),
|
||||
m_object(item)
|
||||
ToggleMenu(tm, imgctrl, layer),
|
||||
m_object(item), m_screen(screen)
|
||||
{
|
||||
setLabel(title);
|
||||
reloadHeads();
|
||||
}
|
||||
|
||||
template <typename ItemType>
|
||||
void XineramaHeadMenu<ItemType>::reloadHeads()
|
||||
{
|
||||
removeAll();
|
||||
FbTk::RefCount<FbTk::Command<void> > saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
|
||||
*Fluxbox::instance(),
|
||||
&Fluxbox::save_rc));
|
||||
char tname[128];
|
||||
for (int i=1; i <= screen.numHeads(); ++i) {
|
||||
for (int i=1; i <= m_screen.numHeads(); ++i) {
|
||||
// TODO: nls
|
||||
/*
|
||||
sprintf(tname, I18n::instance()->
|
||||
|
|
|
@ -844,6 +844,7 @@ void Fluxbox::handleEvent(XEvent * const e) {
|
|||
|
||||
#ifdef HAVE_RANDR
|
||||
if (e->type == m_randr_event_type) {
|
||||
XRRUpdateConfiguration(e);
|
||||
// update root window size in screen
|
||||
BScreen *scr = searchScreen(e->xany.window);
|
||||
if (scr != 0)
|
||||
|
|
Loading…
Reference in a new issue