Index: src/FbPager.cc =================================================================== --- src/FbPager.cc (revision 70) +++ src/FbPager.cc (working copy) @@ -155,6 +155,9 @@ m_follow_drag(m_resmanager, false, "fbpager.followDrag", "FbPager.FollowDrag"), + m_follow_move(m_resmanager, false, + "fbpager.followMove", + "FbPager.FollowMove"), m_change_workspace_button(m_resmanager, "11", "fbpager.changeWorkspaceButton", "FbPager.ChangeWorkspaceButton"), @@ -185,6 +188,9 @@ m_align(m_resmanager, LEFT_TO_RIGHT, "fbpager.align", "FbPager.Align"), + m_color_str(m_resmanager, "white", + "fbpager.color", + "FbPager.Color"), m_window_color_str(m_resmanager, "white", "fbpager.windowColor", "FbPager.WindowColor"), @@ -203,6 +209,12 @@ m_multiclick_time(m_resmanager, 250, "fbpager.multiClickTime", "FbPager.MultiClickTime"), + m_window_icons(m_resmanager, false, + "fbpager.icons", + "FbPager.Icons"), + m_window_border_width(m_resmanager, 1, + "fbpager.windowBorderWidth", + "FbPager.WindowBorderWidth"), m_last_workspace_num(-1) { @@ -217,7 +229,8 @@ FbTk::EventManager::instance()->add(*this, m_window); // setup client window - m_window.setBackgroundColor(FbTk::Color("white", m_window.screenNumber())); + m_window.setBackgroundColor(FbTk::Color((*m_color_str).c_str(), m_window.screenNumber())); + m_window.setAlpha(*m_alpha); Display *disp = FbTk::App::instance()->display(); @@ -452,7 +465,7 @@ m_move_window.client = ClientWindow(0); m_move_window.curr_window = 0; m_move_window.curr_workspace = 0; - m_button_queue.clear(); + m_button_queue.erase(); } else if (compareButtonQueues(m_button_queue, *m_change_workspace_button)) { // change workspace @@ -488,6 +501,7 @@ client.raise(); } else if (compareButtonQueues(m_button_queue, *m_lower_window_button) && client.window() != 0) { + std::cout << "hello world\n"; client.lower(); } else if (compareButtonQueues(m_button_queue, *m_close_window_button) && client.window() != 0) { @@ -511,7 +525,7 @@ return; } - m_button_queue.clear(); + m_button_queue.erase(); } void FbPager::motionNotifyEvent(XMotionEvent &event) { @@ -554,6 +568,16 @@ respectConstraints(newx, newy, *m_move_window.curr_window, workspace->window()); m_move_window.curr_window->move(newx, newy); + if (*m_follow_move) { + + FbTk::FbWindow &win = *m_move_window.curr_window; + int client_x = win.x(), client_y = win.y(); + scaleFromWindowToWindow(*(win.parent()), + m_rootwin, + client_x, client_y); + m_move_window.client.move(client_x, client_y); + } + // drag between the workspaces } else if (m_last_button_event.button == *m_drag_to_workspace_button) { @@ -669,7 +693,9 @@ wincolor, bordercol, backgroundcol, - "workspace"); + "workspace", + *m_window_icons, + *m_window_border_width); w->setAlpha(*m_alpha); m_workspaces.push_back(w); } @@ -843,6 +869,7 @@ cerr<<"Failed to load resource file: "<c_str(), m_window.screenNumber()); for (size_t workspace = 0; workspace < m_workspaces.size(); ++workspace) { m_workspaces[workspace]->setAlpha(*m_alpha); Index: src/Workspace.cc =================================================================== --- src/Workspace.cc (revision 70) +++ src/Workspace.cc (working copy) @@ -30,6 +30,8 @@ #include "ScaleWindowToWindow.hh" #include "FbRootWindow.hh" +#include + #include #include #include @@ -44,7 +46,9 @@ const FbTk::Color &focused_win_color, const FbTk::Color &wincolor, const FbTk::Color &border_color, const FbTk::Color &background_color, - const char *name): + const char *name, + const bool use_pixmap, + const int window_border_width): m_name(name ? name : ""), m_window(parent, 0, 0, // position @@ -54,7 +58,9 @@ m_window_color(wincolor), m_focused_window_color(focused_win_color), m_window_bordercolor(border_color), - m_focused_window(0) { + m_focused_window(0), + m_use_pixmap(use_pixmap), + m_window_border_width(window_border_width) { m_window.setBackgroundColor(background_color); FbTk::EventManager::instance()->add(evh, m_window); @@ -93,18 +99,17 @@ FbTk::EventManager::instance()->add(m_eventhandler, *fbwin); FbTk::EventManager::instance()->add(m_eventhandler, win); - // add window to list and select input + // add window to list m_windowlist[win] = fbwin; - + // update pos and size updateGeometry(win); fbwin->show(); - - fbwin->setBackgroundColor(m_window_color); - fbwin->setBorderWidth(1); + fbwin->setBorderWidth(m_window_border_width); fbwin->setBorderColor(m_window_bordercolor); + updateBackground(win, m_window_color); } void Workspace::resize(unsigned int width, unsigned int height) { @@ -168,8 +173,8 @@ WindowList::iterator it = m_windowlist.begin(); WindowList::iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { - (*it).second->setBackgroundColor(m_window_color); (*it).second->setBorderColor(m_window_bordercolor); + updateBackground((*it).first, m_window_color); } updateFocusedWindow(); } @@ -188,8 +193,12 @@ m_window.clear(); WindowList::iterator it = m_windowlist.begin(); WindowList::iterator it_end = m_windowlist.end(); - for (; it != it_end; ++it) + for (; it != it_end; ++it) { + if (m_use_pixmap) { + updateBackground((*it).first,m_window_color); + } (*it).second->clear(); + } } void Workspace::remove(Window win) { @@ -200,6 +209,7 @@ FbTk::EventManager::instance()->remove(win); delete fbwin; + if (fbwin == m_focused_window) m_focused_window = 0; @@ -210,7 +220,7 @@ WindowList::const_iterator it = m_windowlist.begin(); WindowList::const_iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { - if (*(*it).second == win) + if ((*it).first == win) return ClientWindow((*it).first); } return ClientWindow(0); @@ -238,33 +248,41 @@ return 0; } - void Workspace::updateFocusedWindow() { if (s_focused_window == 0) return; - - FbTk::FbWindow *win = find(s_focused_window); - if (win == m_focused_window) + + FbTk::FbWindow *fbwin = find(s_focused_window); + if (fbwin == m_focused_window) return; if (m_focused_window != 0) { - m_focused_window->setBackgroundColor(m_window_color); + + updateBackground(m_focused_window->window(), m_window_color); m_focused_window->clear(); } - if (win == 0) { + if (fbwin == 0) { m_focused_window = 0; return; } - win->setBackgroundColor(m_focused_window_color); - win->clear(); - m_focused_window = win; + WindowList::const_iterator it = m_windowlist.begin(); + WindowList::const_iterator it_end = m_windowlist.end(); + for (; it != it_end; ++it) { + if ((*it).second == fbwin ) + break; + } + + updateBackground((*it).first, m_focused_window_color); + fbwin->clear(); + m_focused_window = fbwin; } void Workspace::updateGeometry(Window win) { - FbTk::FbWindow *fbwin = find(win); - if (fbwin == 0) + + FbTk::FbWindow* fbwin= find(win); + if (!fbwin) return; int x = 0, y = 0; @@ -287,7 +305,32 @@ h = 1; fbwin->moveResize(x, y, w, h); + updateBackground(win, m_window_color); } +void Workspace::updateBackground(Window win, const FbTk::Color &bg_color) { + + FbTk::FbWindow* fbwin= find(win); + if (!fbwin ) + return; + + + if (m_use_pixmap) { + XWMHints *hints = XGetWMHints(FbTk::App::instance()->display(), win); + if (hints && (hints->flags & IconPixmapHint) && hints->icon_pixmap != 0) { + FbTk::FbPixmap fbpix; + fbpix.copy(hints->icon_pixmap); + fbpix.scale(fbwin->width(), fbwin->height()); + fbwin->setBackgroundPixmap(fbpix.drawable()); + } + else + fbwin->setBackgroundColor(bg_color); + + XFree(hints); + } + else + fbwin->setBackgroundColor(bg_color); +} + }; // end namespace FbPager Index: src/FbPager.hh =================================================================== --- src/FbPager.hh (revision 70) +++ src/FbPager.hh (working copy) @@ -124,6 +124,7 @@ FbTk::Resource m_workspace_width, m_workspace_height; FbTk::Resource m_workspaces_per_row; FbTk::Resource m_follow_drag; + FbTk::Resource m_follow_move; FbTk::Resource m_change_workspace_button; FbTk::Resource m_raise_window_button; @@ -136,11 +137,14 @@ FbTk::Resource m_drag_to_workspace_button; FbTk::Resource m_align; + FbTk::Resource m_color_str; FbTk::Resource m_window_color_str, m_focused_window_color_str; FbTk::Resource m_window_bordercolor_str; FbTk::Resource m_background_color_str; FbTk::Resource m_current_background_color_str; FbTk::Resource m_multiclick_time; + FbTk::Resource m_window_icons; + FbTk::Resource m_window_border_width; std::string m_button_queue; XButtonEvent m_last_button_event; Index: src/Workspace.hh =================================================================== --- src/Workspace.hh (revision 70) +++ src/Workspace.hh (working copy) @@ -25,6 +25,7 @@ #define FBPAGER_WORKSPACE_HH #include "FbTk/FbWindow.hh" +#include "FbTk/FbPixmap.hh" #include "FbTk/NotCopyable.hh" #include "FbTk/EventHandler.hh" #include "FbTk/Color.hh" @@ -50,7 +51,9 @@ const FbTk::Color &wincolor, const FbTk::Color &border_color, const FbTk::Color &background_color, - const char *name = 0); + const char *name = 0, + const bool use_pixmap = true, + const int window_border_width = 1); /// destructor ~Workspace(); /// set new name for this workspace @@ -93,17 +96,23 @@ static void setFocusedWindow(Window win) { s_focused_window = win; } private: + + void updateBackground(Window win, const FbTk::Color& bg_color); + std::string m_name; ///< name of this workspace FbTk::FbWindow m_window; ///< FbWindow of this workspace FbTk::EventHandler &m_eventhandler; - typedef std::map WindowList; + typedef std::map WindowList; WindowList m_windowlist; ///< holds a set of Window to FbWindow association FbTk::Color m_window_color, m_focused_window_color, m_window_bordercolor; FbTk::FbWindow *m_focused_window; static Window s_focused_window; + + bool m_use_pixmap; + int m_window_border_width; }; Index: src/FbTk/FbPixmap.hh =================================================================== --- src/FbTk/FbPixmap.hh (revision 0) +++ src/FbTk/FbPixmap.hh (revision 0) @@ -0,0 +1,83 @@ +// FbPixmap.hh for FbTk - Fluxbox ToolKit +// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +// $Id: FbPixmap.hh,v 1.10 2004/01/11 12:48:46 fluxgen Exp $ + +#ifndef FBTK_FBPIXMAP_HH +#define FBTK_FBPIXMAP_HH + +#include "FbDrawable.hh" + +#include + +namespace FbTk { + +/// a wrapper for X Pixmap +class FbPixmap:public FbDrawable { +public: + FbPixmap(); + /// copy pixmap + explicit FbPixmap(const FbPixmap ©); + /// creates a FbPixmap from X pixmap + explicit FbPixmap(Pixmap pm); + FbPixmap(const FbDrawable &src, + unsigned int width, unsigned int height, + int depth); + FbPixmap(Drawable src, + unsigned int width, unsigned int height, + int depth); + + virtual ~FbPixmap(); + + void copy(const FbPixmap &the_copy); + void copy(Pixmap pixmap); + /// rotates the pixmap 90 deg, not implemented! + void rotate(); + /// scales the pixmap to specified size + void scale(unsigned int width, unsigned int height); + void resize(unsigned int width, unsigned int height); + /// drops pixmap and returns it + Pixmap release(); + + FbPixmap &operator = (const FbPixmap ©); + /// sets new pixmap + FbPixmap &operator = (Pixmap pm); + + inline Drawable drawable() const { return m_pm; } + inline unsigned int width() const { return m_width; } + inline unsigned int height() const { return m_height; } + inline int depth() const { return m_depth; } + + +private: + void free(); + void create(Drawable src, + unsigned int width, unsigned int height, + int depth); + Pixmap m_pm; + unsigned int m_width, m_height; + int m_depth; +}; + +} // end namespace FbTk + +#endif // FBTK_FBPIXMAP_HH + Index: src/FbTk/FbPixmap.cc =================================================================== --- src/FbTk/FbPixmap.cc (revision 0) +++ src/FbTk/FbPixmap.cc (revision 0) @@ -0,0 +1,291 @@ +// FbPixmap.cc for FbTk - Fluxbox ToolKit +// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +// $Id: FbPixmap.cc,v 1.10 2004/01/11 12:48:46 fluxgen Exp $ + +#include "FbPixmap.hh" +#include "App.hh" +#include "GContext.hh" + +#include +#include +using namespace std; + +namespace FbTk { + +FbPixmap::FbPixmap():m_pm(0), + m_width(0), m_height(0), + m_depth(0) { } + +FbPixmap::FbPixmap(const FbPixmap &the_copy):m_pm(0), + m_width(0), m_height(0), + m_depth(0) { + copy(the_copy); +} + +FbPixmap::FbPixmap(Pixmap pm):m_pm(0), + m_width(0), m_height(0), + m_depth(0) { + if (pm == 0) + return; + // assign X pixmap to this + (*this) = pm; +} + +FbPixmap::FbPixmap(const FbDrawable &src, + unsigned int width, unsigned int height, + int depth):m_pm(0), + m_width(0), m_height(0), + m_depth(0) { + + create(src.drawable(), width, height, depth); +} + +FbPixmap::FbPixmap(Drawable src, + unsigned int width, unsigned int height, + int depth):m_pm(0), + m_width(0), m_height(0), + m_depth(0) { + + create(src, width, height, depth); +} + +FbPixmap::~FbPixmap() { + free(); +} + +FbPixmap &FbPixmap::operator = (const FbPixmap &the_copy) { + copy(the_copy); + return *this; +} + +FbPixmap &FbPixmap::operator = (Pixmap pm) { + // free pixmap before we set new + free(); + + if (pm == 0) + return *this; + + // get width, height and depth for the pixmap + Window root; + int x, y; + unsigned int border_width, bpp; + XGetGeometry(FbTk::App::instance()->display(), + pm, + &root, + &x, &y, + &m_width, &m_height, + &border_width, + &bpp); + + m_depth = bpp; + + m_pm = pm; + + return *this; +} + +void FbPixmap::copy(const FbPixmap &the_copy) { + + bool create_new = false; + + if (the_copy.width() != width() || + the_copy.height() != height() || + the_copy.depth() != depth() || + drawable() == 0) + create_new = true; + + if (create_new) + free(); + + if (the_copy.drawable() != 0) { + if (create_new) { + create(the_copy.drawable(), + the_copy.width(), the_copy.height(), + the_copy.depth()); + } + + if (drawable()) { + GContext gc(drawable()); + + copyArea(the_copy.drawable(), + gc.gc(), + 0, 0, + 0, 0, + width(), height()); + } + } +} + +void FbPixmap::copy(Pixmap pm) { + free(); + if (pm == 0) + return; + + // get width, height and depth for the pixmap + Window root; + int x, y; + unsigned int border_width, bpp; + unsigned int new_width, new_height; + + XGetGeometry(FbTk::App::instance()->display(), + pm, + &root, + &x, &y, + &new_width, &new_height, + &border_width, + &bpp); + // create new pixmap and copy area + create(root, new_width, new_height, bpp); + + Display *disp = FbTk::App::instance()->display(); + + GC gc = XCreateGC(disp, drawable(), 0, 0); + + XCopyArea(disp, pm, drawable(), gc, + 0, 0, + width(), height(), + 0, 0); + + XFreeGC(disp, gc); +} + +void FbPixmap::rotate() { + + Display *dpy = FbTk::App::instance()->display(); + + // make an image copy + XImage *src_image = XGetImage(dpy, drawable(), + 0, 0, // pos + width(), height(), // size + ~0, // plane mask + ZPixmap); // format + // reverse height/width for new pixmap + FbPixmap new_pm(drawable(), height(), width(), depth()); + + GContext gc(drawable()); + + // copy new area + for (int y = 0; y < static_cast(height()); ++y) { + for (int x = 0; x < static_cast(width()); ++x) { + gc.setForeground(XGetPixel(src_image, x, y)); + // revers coordinates + XDrawPoint(dpy, new_pm.drawable(), gc.gc(), y, x); + } + } + + XDestroyImage(src_image); + // free old pixmap and set new from new_pm + free(); + + m_width = new_pm.width(); + m_height = new_pm.height(); + m_depth = new_pm.depth(); + m_pm = new_pm.release(); +} + +void FbPixmap::scale(unsigned int dest_width, unsigned int dest_height) { + if (drawable() == 0 || + (dest_width == width() && dest_height == height())) + return; + + Display *dpy = FbTk::App::instance()->display(); + + XImage *src_image = XGetImage(dpy, drawable(), + 0, 0, // pos + width(), height(), // size + ~0, // plane mask + ZPixmap); // format + if (src_image == 0) + return; + + // create new pixmap with dest size + FbPixmap new_pm(drawable(), dest_width, dest_height, depth()); + + GContext gc(drawable()); + // calc zoom + float zoom_x = static_cast(width())/static_cast(dest_width); + float zoom_y = static_cast(height())/static_cast(dest_height); + + // start scaling + float src_x = 0, src_y = 0; + for (int tx=0; tx < static_cast(dest_width); ++tx, src_x += zoom_x) { + src_y = 0; + for (int ty=0; ty < static_cast(dest_height); ++ty, src_y += zoom_y) { + gc.setForeground(XGetPixel(src_image, + static_cast(src_x), + static_cast(src_y))); + XDrawPoint(dpy, new_pm.drawable(), gc.gc(), tx, ty); + } + } + + XDestroyImage(src_image); + + // free old pixmap and set new from new_pm + free(); + + m_width = new_pm.width(); + m_height = new_pm.height(); + m_depth = new_pm.depth(); + m_pm = new_pm.release(); +} + +void FbPixmap::resize(unsigned int width, unsigned int height) { + FbPixmap pm(drawable(), width, height, depth()); + *this = pm.release(); +} + +Pixmap FbPixmap::release() { + Pixmap ret = m_pm; + m_pm = 0; + m_width = 0; + m_height = 0; + m_depth = 0; + return ret; +} + +void FbPixmap::free() { + if (m_pm != 0) { + XFreePixmap(FbTk::App::instance()->display(), m_pm); + m_pm = 0; + } + m_width = 0; + m_height = 0; + m_depth = 0; +} + +void FbPixmap::create(Drawable src, + unsigned int width, unsigned int height, + int depth) { + if (src == 0) + return; + + m_pm = XCreatePixmap(FbTk::App::instance()->display(), + src, width, height, depth); + if (m_pm == 0) + return; + + m_width = width; + m_height = height; + m_depth = depth; +} + +}; // end namespace FbTk Index: src/FbTk/Makefile.am =================================================================== --- src/FbTk/Makefile.am (revision 70) +++ src/FbTk/Makefile.am (working copy) @@ -4,6 +4,7 @@ App.hh App.cc Color.cc Color.hh \ EventHandler.hh EventManager.hh EventManager.cc \ FbWindow.hh FbWindow.cc\ + FbPixmap.hh FbPixmap.cc\ NotCopyable.hh \ Transparent.hh Transparent.cc \ Resource.hh Resource.cc \