all repos — fluxbox @ 4d77f7fbf188759a8feb50f51c1573b86b48663b

custom fork of the fluxbox windowmanager

new background style item, making rootCommand in styles obsolete
fluxgen fluxgen
commit

4d77f7fbf188759a8feb50f51c1573b86b48663b

parent

e62176913405f98fce84a19d63cb211c6cfc3713

5 files changed, 258 insertions(+), 44 deletions(-)

jump to
M ChangeLogChangeLog

@@ -1,5 +1,28 @@

(Format: Year/Month/Day) Changes for 0.9.15: +*05/11/22: + * New theme item: + background: <texture option> + background.pixmap: <image filename> + background.color: <color> + background.colorTo: <color> + The background.pixmap filename will be sent to "fbsetbg" + which in turn sets the background. + The following options will be available for the background.pixmap: + - tiled + - centered + For example: + background: tiled + background.pixmap: someimage.png + and it can also generate a normal texture: + background: gradient + background.color: blue + background.colorTo: green + The rootCommand in the style is now obsolete and + if the "background" item is not found in the style then the default + background will be black and with a warning text. + (Henrik) + RootTheme.hh/cc, Screen.cc *05/11/16: * Added styleOverlay resource to init-file (Mathias) session.styleOverlay: ~/.fluxbox/overlay
M src/RootTheme.ccsrc/RootTheme.cc

@@ -23,38 +23,216 @@ // $Id$

#include "RootTheme.hh" +#include "FbRootWindow.hh" #include "FbCommands.hh" + #include "FbTk/App.hh" +#include "FbTk/Font.hh" +#include "FbTk/ImageControl.hh" +#include "FbTk/Resource.hh" +#include "FbTk/FileUtil.hh" +#include "FbTk/StringUtil.hh" +#include "FbTk/TextureRender.hh" -RootTheme::RootTheme(int screen_num, std::string &screen_root_command): - FbTk::Theme(screen_num), - m_root_command(*this, "rootCommand", "RootCommand"), - m_screen_root_command(screen_root_command), - m_opgc(RootWindow(FbTk::App::instance()->display(), screen_num)), - m_lock(false) { - + +#include <X11/Xatom.h> + +using std::string; + +class BackgroundItem: public FbTk::ThemeItem<FbTk::Texture> { +public: + BackgroundItem(FbTk::Theme &tm, const std::string &name, const std::string &altname): + FbTk::ThemeItem<FbTk::Texture>(tm, name, altname) { + + } + + void load(const std::string *o_name = 0, const std::string *o_altname = 0) { + const string &m_name = (o_name == 0) ? name() : *o_name; + const string &m_altname = (o_altname == 0) ? altName() : *o_altname; + + // create subnames + string color_name(FbTk::ThemeManager::instance(). + resourceValue(m_name + ".color", m_altname + ".Color")); + string colorto_name(FbTk::ThemeManager::instance(). + resourceValue(m_name + ".colorTo", m_altname + ".ColorTo")); + string pixmap_name(FbTk::ThemeManager::instance(). + resourceValue(m_name + ".pixmap", m_altname + ".Pixmap")); + + + // set default value if we failed to load colors + if (!(*this)->color().setFromString(color_name.c_str(), + theme().screenNum())) + (*this)->color().setFromString("darkgray", theme().screenNum()); + + if (!(*this)->colorTo().setFromString(colorto_name.c_str(), + theme().screenNum())) + (*this)->colorTo().setFromString("white", theme().screenNum()); + + + if (((*this)->type() & FbTk::Texture::SOLID) != 0 && ((*this)->type() & FbTk::Texture::FLAT) == 0) + (*this)->calcHiLoColors(theme().screenNum()); + + // remove whitespace and set filename + FbTk::StringUtil::removeFirstWhitespace(pixmap_name); + FbTk::StringUtil::removeTrailingWhitespace(pixmap_name); + m_filename = pixmap_name; + + // we dont load any pixmap, using external command to set background pixmap + (*this)->pixmap() = 0; + } + + void setFromString(const char *str) { + m_options = str; // save option string + FbTk::ThemeItem<FbTk::Texture>::setFromString(str); + } + const std::string &filename() const { return m_filename; } + const std::string &options() const { return m_options; } +private: + std::string m_filename, m_options; +}; + + +RootTheme::RootTheme(const std::string &root_command, + FbTk::ImageControl &image_control): + FbTk::Theme(image_control.screenNumber()), + m_background(new BackgroundItem(*this, "background", "Background")), + m_opgc(RootWindow(FbTk::App::instance()->display(), image_control.screenNumber())), + m_root_command(root_command), + m_image_ctrl(image_control), + m_lock(false), + m_background_loaded(true) { + Display *disp = FbTk::App::instance()->display(); - m_opgc.setForeground(WhitePixel(disp, screen_num)^BlackPixel(disp, screen_num)); + m_opgc.setForeground(WhitePixel(disp, screenNum())^BlackPixel(disp, screenNum())); m_opgc.setFunction(GXxor); m_opgc.setSubwindowMode(IncludeInferiors); m_opgc.setLineAttributes(1, LineSolid, CapNotLast, JoinMiter); } RootTheme::~RootTheme() { + delete m_background; +} +bool RootTheme::fallback(FbTk::ThemeItem_base &item) { + // if background theme item was not found in the + // style then mark background as not loaded so + // we can deal with it in reconfigureTheme() + if (item.name() == "background") { + // mark no background loaded + m_background_loaded = false; + return true; + } + return false; } void RootTheme::reconfigTheme() { if (m_lock) return; - - // override resource root command? - if (m_screen_root_command == "") { - // do root command - FbCommands::ExecuteCmd cmd(*m_root_command, screenNum()); + // if user specified background in the config then use it + // instead of style background + if (!m_root_command.empty()) { + FbCommands::ExecuteCmd cmd(m_root_command, screenNum()); cmd.execute(); + return; + } + + // + // Else parse background from style + // + + // root window helper + FbRootWindow rootwin(screenNum()); + + // if the background theme item was not loaded + // then generate an image with a text that + // notifies the user about it + + if (!m_background_loaded) { + FbTk::FbPixmap root(FbTk::FbPixmap::getRootPixmap(screenNum())); + // if there is no root background pixmap + // then we need to create one + if (root.drawable() == None) { + root.create(rootwin.window(), + rootwin.width(), rootwin.height(), + rootwin.depth()); + + FbTk::FbPixmap::setRootPixmap(screenNum(), root.drawable()); + } + + // setup root window property + Atom atom_root = XInternAtom(rootwin.display(), "_XROOTPMAP_ID", false); + Pixmap pm = root.drawable(); + rootwin.changeProperty(atom_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&pm, 1); + rootwin.setBackgroundPixmap(root.drawable()); + + + FbTk::GContext gc(root); + + // fill background color + gc.setForeground(FbTk::Color("black", screenNum())); + root.fillRectangle(gc.gc(), + 0, 0, + root.width(), root.height()); + // text color + gc.setForeground(FbTk::Color("white", screenNum())); + // render text + const char errormsg[] = + "There is no background option specified in this style. Please consult the manual or read the FAQ."; + FbTk::Font font; + font.drawText(root, screenNum(), gc.gc(), + errormsg, strlen(errormsg), + 2, font.height() + 2); // added some extra pixels for better visibility + + + // reset background mark + m_background_loaded = true; + root.release(); // we dont want to destroy this pixmap } else { - FbCommands::ExecuteCmd cmd(m_screen_root_command, screenNum()); - cmd.execute(); + // handle background option in style + std::string filename = m_background->filename(); + FbTk::StringUtil::removeTrailingWhitespace(filename); + FbTk::StringUtil::removeFirstWhitespace(filename); + // if background argument is a file then + // parse image options and call image setting + // command specified in the resources + if (FbTk::FileUtil::isRegularFile(filename.c_str())) { + // parse options + std::string options; + if (strstr(m_background->options().c_str(), "tiled") != 0) + options += "-t "; + if (strstr(m_background->options().c_str(), "centered") != 0) + options += "-c "; + + // compose wallpaper application "fbsetbg" with argumetns + std::string commandargs = "fbsetbg " + options + " " + filename; + + // call command with options + FbCommands::ExecuteCmd exec(commandargs, screenNum()); + exec.execute(); + + } else { + // render normal texture + + // we override the image control renderImage since + // since we do not want to cache this pixmap + XColor *colors; + int num_colors; + m_image_ctrl.getXColorTable(&colors, &num_colors); + FbTk::TextureRender image(m_image_ctrl, rootwin.width(), rootwin.height(), + colors, num_colors); + Pixmap pixmap = image.render(*(*m_background)); + // setup root window property + Atom atom_root = XInternAtom(rootwin.display(), "_XROOTPMAP_ID", false); + rootwin.changeProperty(atom_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&pixmap, 1); + rootwin.setBackgroundPixmap(pixmap); + + } + } + + // clear root window + rootwin.clear(); + + + }
M src/RootTheme.hhsrc/RootTheme.hh

@@ -26,21 +26,30 @@ #define ROOTTHEME_HH

#include "FbTk/Theme.hh" #include "FbTk/GContext.hh" +#include "FbTk/Texture.hh" #include <X11/Xlib.h> #include <string> +class BackgroundItem; + +namespace FbTk { +class ResourceManager; +class ImageControl; +} /// Contains border color, border size, bevel width and opGC for objects like geometry window in BScreen class RootTheme: public FbTk::Theme { public: /// constructor - /// @param screen_num the screen number - /// @param screen_root_command the string to be executed override theme rootCommand - RootTheme(int screen_num, std::string &screen_root_command); + /// @param resmanager resource manager for finding specific resources + /// @param image_control for rendering background texture + RootTheme(const std::string &root_command, + FbTk::ImageControl &image_control); ~RootTheme(); + bool fallback(FbTk::ThemeItem_base &item); void reconfigTheme(); GC opGC() const { return m_opgc.gc(); }

@@ -55,10 +64,13 @@

//!! TODO we should need this later void lock(bool value) { m_lock = value; } private: - FbTk::ThemeItem<std::string> m_root_command; - std::string &m_screen_root_command; ///< string to execute and override theme rootCommand + BackgroundItem *m_background;///< background image/texture FbTk::GContext m_opgc; - bool m_lock; + const std::string &m_root_command; + FbTk::ImageControl &m_image_ctrl; ///< image control for rendering background texture + bool m_lock; ///< reconfigure lock + bool m_background_loaded; ///< whether or not the background is present in the style file + }; #endif // ROOTTHEME_HH
M src/Screen.ccsrc/Screen.cc

@@ -229,9 +229,6 @@ // because winbutton need to rescale the pixmaps in winbutton theme

// after fbwinframe have resized them m_winbutton_theme(new WinButtonTheme(scrn, *m_windowtheme)), m_menutheme(new MenuTheme(scrn)), - m_root_theme(new - RootTheme(scrn, - *resource.rootcommand)), m_root_window(scrn), m_geom_window(m_root_window, 0, 0, 10, 10,

@@ -249,8 +246,7 @@ m_xinerama_headinfo(0),

m_shutdown(false) { - Fluxbox *fluxbox = Fluxbox::instance(); - Display *disp = fluxbox->display(); + Display *disp = m_root_window.display(); initXinerama();

@@ -261,7 +257,7 @@ rootWindow().setEventMask(ColormapChangeMask | EnterWindowMask | PropertyChangeMask |

SubstructureRedirectMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask| SubstructureNotifyMask); - fluxbox->sync(false); + FbTk::App::instance()->sync(false); XSetErrorHandler((XErrorHandler) old);

@@ -286,13 +282,17 @@

rootWindow().setCursor(XCreateFontCursor(disp, XC_left_ptr)); // load this screens resources + Fluxbox *fluxbox = Fluxbox::instance(); fluxbox->load_rc(*this); // setup image cache engine - m_image_control.reset(new FbTk::ImageControl(scrn, true, fluxbox->colorsPerChannel(), + m_image_control.reset(new FbTk::ImageControl(scrn, true, + fluxbox->colorsPerChannel(), fluxbox->getCacheLife(), fluxbox->getCacheMax())); imageControl().installRootColormap(); root_colormap_installed = true; + + m_root_theme.reset(new RootTheme(*resource.rootcommand, imageControl())); m_windowtheme->setFocusedAlpha(*resource.focused_alpha); m_windowtheme->setUnfocusedAlpha(*resource.unfocused_alpha);

@@ -778,12 +778,12 @@ // reconfigure workspaces

for_each(m_workspaces_list.begin(), m_workspaces_list.end(), mem_fun(&Workspace::reconfigure)); - + // reconfigure Icons for_each(m_icon_list.begin(), m_icon_list.end(), mem_fun(&FluxboxWindow::reconfigure)); - + imageControl().cleanCache(); // notify objects that the screen is reconfigured m_reconfigure_sig.notify();
M src/ScreenResources.ccsrc/ScreenResources.cc

@@ -44,7 +44,7 @@ setDefaultValue();

} template <> -string FbTk::Resource<BScreen::PlacementPolicy>::getString() { +string FbTk::Resource<BScreen::PlacementPolicy>::getString() const { switch (*(*this)) { case BScreen::ROWSMARTPLACEMENT: return "RowSmartPlacement";

@@ -71,7 +71,7 @@

} template <> -string FbTk::Resource<BScreen::RowDirection>::getString() { +string FbTk::Resource<BScreen::RowDirection>::getString() const { switch (*(*this)) { case BScreen::LEFTRIGHT: return "LeftToRight";

@@ -95,7 +95,7 @@

} template <> -string FbTk::Resource<BScreen::ColumnDirection>::getString() { +string FbTk::Resource<BScreen::ColumnDirection>::getString() const { switch (*(*this)) { case BScreen::TOPBOTTOM: return "TopToBottom";

@@ -107,7 +107,7 @@ return "TopToBottom";

} template <> -string FbTk::Resource<FbTk::MenuTheme::MenuMode>::getString() { +string FbTk::Resource<FbTk::MenuTheme::MenuMode>::getString() const { switch (*(*this)) { case FbTk::MenuTheme::DELAY_OPEN: return string("Delay");

@@ -127,14 +127,14 @@ else

setDefaultValue(); } -template<> -std::string FbTk::Resource<BScreen::ResizeModel>::getString() { + +std::string FbTk::Resource<BScreen::ResizeModel>::getString() const { switch (m_value) { case BScreen::QUADRANTRESIZE: return std::string("Quadrant"); case BScreen::BOTTOMRESIZE: return std::string("Bottom"); - }; + } return std::string("Default"); }

@@ -151,7 +151,7 @@ m_value = BScreen::DEFAULTRESIZE;

} template<> -std::string FbTk::Resource<BScreen::FocusModel>::getString() { +std::string FbTk::Resource<BScreen::FocusModel>::getString() const { switch (m_value) { case BScreen::MOUSEFOCUS: return string("MouseFocus");

@@ -174,7 +174,8 @@ setDefaultValue();

} template<> -std::string FbTk::Resource<BScreen::TabFocusModel>::getString() { + +std::string FbTk::Resource<BScreen::TabFocusModel>::getString() const { switch (m_value) { case BScreen::MOUSETABFOCUS: return string("SloppyTabFocus");

@@ -197,7 +198,7 @@ setDefaultValue();

} template<> -std::string FbTk::Resource<BScreen::FollowModel>::getString() { +std::string FbTk::Resource<BScreen::FollowModel>::getString() const { switch (m_value) { case BScreen::FOLLOW_ACTIVE_WINDOW: return std::string("Follow");

@@ -205,7 +206,7 @@ break;

case BScreen::FETCH_ACTIVE_WINDOW: return std::string("Current"); break; - }; + } return std::string("Ignore"); }

@@ -224,7 +225,7 @@ setDefaultValue();

} template<> -std::string FbTk::Resource<FbTk::GContext::LineStyle>::getString() { +std::string FbTk::Resource<FbTk::GContext::LineStyle>::getString() const { switch(m_value) { case FbTk::GContext::LINESOLID: return "LineSolid";

@@ -254,7 +255,7 @@ setDefaultValue();

} template<> -std::string FbTk::Resource<FbTk::GContext::JoinStyle>::getString() { +std::string FbTk::Resource<FbTk::GContext::JoinStyle>::getString() const { switch(m_value) { case FbTk::GContext::JOINMITER: return "JoinMiter";

@@ -284,7 +285,7 @@ setDefaultValue();

} template<> -std::string FbTk::Resource<FbTk::GContext::CapStyle>::getString() { +std::string FbTk::Resource<FbTk::GContext::CapStyle>::getString() const { switch(m_value) { case FbTk::GContext::CAPNOTLAST: return "CapNotLast";