From 4d77f7fbf188759a8feb50f51c1573b86b48663b Mon Sep 17 00:00:00 2001 From: fluxgen Date: Tue, 22 Nov 2005 21:59:48 +0000 Subject: new background style item, making rootCommand in styles obsolete --- ChangeLog | 23 ++++++ src/RootTheme.cc | 208 +++++++++++++++++++++++++++++++++++++++++++++---- src/RootTheme.hh | 24 ++++-- src/Screen.cc | 18 ++--- src/ScreenResources.cc | 29 +++---- 5 files changed, 258 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 13c3c25..85e5286 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,28 @@ (Format: Year/Month/Day) Changes for 0.9.15: +*05/11/22: + * New theme item: + background: + background.pixmap: + background.color: + background.colorTo: + 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 diff --git a/src/RootTheme.cc b/src/RootTheme.cc index 9d73477..dea61cf 100644 --- a/src/RootTheme.cc +++ b/src/RootTheme.cc @@ -23,38 +23,216 @@ #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" + + +#include + +using std::string; + +class BackgroundItem: public FbTk::ThemeItem { +public: + BackgroundItem(FbTk::Theme &tm, const std::string &name, const std::string &altname): + FbTk::ThemeItem(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::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) { -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) { - 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(); + + + } diff --git a/src/RootTheme.hh b/src/RootTheme.hh index dce9d31..c1ac060 100644 --- a/src/RootTheme.hh +++ b/src/RootTheme.hh @@ -26,21 +26,30 @@ #include "FbTk/Theme.hh" #include "FbTk/GContext.hh" +#include "FbTk/Texture.hh" #include #include +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 @@ public: //!! TODO we should need this later void lock(bool value) { m_lock = value; } private: - FbTk::ThemeItem 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 diff --git a/src/Screen.cc b/src/Screen.cc index c7fe1d3..b18dcb8 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -229,9 +229,6 @@ BScreen::BScreen(FbTk::ResourceManager &rm, // 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 @@ BScreen::BScreen(FbTk::ResourceManager &rm, m_shutdown(false) { - Fluxbox *fluxbox = Fluxbox::instance(); - Display *disp = fluxbox->display(); + Display *disp = m_root_window.display(); initXinerama(); @@ -261,7 +257,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, SubstructureRedirectMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask| SubstructureNotifyMask); - fluxbox->sync(false); + FbTk::App::instance()->sync(false); XSetErrorHandler((XErrorHandler) old); @@ -286,14 +282,18 @@ BScreen::BScreen(FbTk::ResourceManager &rm, 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); m_menutheme->setAlpha(*resource.menu_alpha); @@ -778,12 +778,12 @@ void BScreen::reconfigure() { 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(); diff --git a/src/ScreenResources.cc b/src/ScreenResources.cc index d541ae7..7d97cd8 100644 --- a/src/ScreenResources.cc +++ b/src/ScreenResources.cc @@ -44,7 +44,7 @@ void FbTk::Resource::setFromString(const char *str) { } template <> -string FbTk::Resource::getString() { +string FbTk::Resource::getString() const { switch (*(*this)) { case BScreen::ROWSMARTPLACEMENT: return "RowSmartPlacement"; @@ -71,7 +71,7 @@ void FbTk::Resource::setFromString(const char *str) { } template <> -string FbTk::Resource::getString() { +string FbTk::Resource::getString() const { switch (*(*this)) { case BScreen::LEFTRIGHT: return "LeftToRight"; @@ -95,7 +95,7 @@ void FbTk::Resource::setFromString(const char *str) { } template <> -string FbTk::Resource::getString() { +string FbTk::Resource::getString() const { switch (*(*this)) { case BScreen::TOPBOTTOM: return "TopToBottom"; @@ -107,7 +107,7 @@ string FbTk::Resource::getString() { } template <> -string FbTk::Resource::getString() { +string FbTk::Resource::getString() const { switch (*(*this)) { case FbTk::MenuTheme::DELAY_OPEN: return string("Delay"); @@ -127,14 +127,14 @@ void FbTk::Resource::setFromString(const char *str) { setDefaultValue(); } -template<> -std::string FbTk::Resource::getString() { + +std::string FbTk::Resource::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 @@ setFromString(char const *strval) { } template<> -std::string FbTk::Resource::getString() { +std::string FbTk::Resource::getString() const { switch (m_value) { case BScreen::MOUSEFOCUS: return string("MouseFocus"); @@ -174,7 +174,8 @@ setFromString(char const *strval) { } template<> -std::string FbTk::Resource::getString() { + +std::string FbTk::Resource::getString() const { switch (m_value) { case BScreen::MOUSETABFOCUS: return string("SloppyTabFocus"); @@ -197,7 +198,7 @@ setFromString(char const *strval) { } template<> -std::string FbTk::Resource::getString() { +std::string FbTk::Resource::getString() const { switch (m_value) { case BScreen::FOLLOW_ACTIVE_WINDOW: return std::string("Follow"); @@ -205,7 +206,7 @@ std::string FbTk::Resource::getString() { case BScreen::FETCH_ACTIVE_WINDOW: return std::string("Current"); break; - }; + } return std::string("Ignore"); } @@ -224,7 +225,7 @@ setFromString(char const *strval) { } template<> -std::string FbTk::Resource::getString() { +std::string FbTk::Resource::getString() const { switch(m_value) { case FbTk::GContext::LINESOLID: return "LineSolid"; @@ -254,7 +255,7 @@ void FbTk::Resource } template<> -std::string FbTk::Resource::getString() { +std::string FbTk::Resource::getString() const { switch(m_value) { case FbTk::GContext::JOINMITER: return "JoinMiter"; @@ -284,7 +285,7 @@ void FbTk::Resource } template<> -std::string FbTk::Resource::getString() { +std::string FbTk::Resource::getString() const { switch(m_value) { case FbTk::GContext::CAPNOTLAST: return "CapNotLast"; -- cgit v0.11.2