fixed root pixmap crash problem, using fbsetroot to render background
This commit is contained in:
parent
97bee9f1be
commit
3ceb311a32
1 changed files with 91 additions and 50 deletions
131
src/RootTheme.cc
131
src/RootTheme.cc
|
@ -33,10 +33,16 @@
|
|||
#include "FbTk/FileUtil.hh"
|
||||
#include "FbTk/StringUtil.hh"
|
||||
#include "FbTk/TextureRender.hh"
|
||||
|
||||
#include "FbTk/I18n.hh"
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
class BackgroundItem: public FbTk::ThemeItem<FbTk::Texture> {
|
||||
|
@ -58,7 +64,8 @@ public:
|
|||
string pixmap_name(FbTk::ThemeManager::instance().
|
||||
resourceValue(m_name + ".pixmap", m_altname + ".Pixmap"));
|
||||
|
||||
|
||||
m_color = color_name;
|
||||
m_color_to = colorto_name;
|
||||
// set default value if we failed to load colors
|
||||
if (!(*this)->color().setFromString(color_name.c_str(),
|
||||
theme().screenNum()))
|
||||
|
@ -87,8 +94,11 @@ public:
|
|||
}
|
||||
const std::string &filename() const { return m_filename; }
|
||||
const std::string &options() const { return m_options; }
|
||||
const std::string &colorString() const { return m_color; }
|
||||
const std::string &colorToString() const { return m_color_to; }
|
||||
private:
|
||||
std::string m_filename, m_options;
|
||||
std::string m_color, m_color_to;
|
||||
};
|
||||
|
||||
|
||||
|
@ -128,6 +138,7 @@ bool RootTheme::fallback(FbTk::ThemeItem_base &item) {
|
|||
void RootTheme::reconfigTheme() {
|
||||
if (m_lock)
|
||||
return;
|
||||
|
||||
// if user specified background in the config then use it
|
||||
// instead of style background
|
||||
if (!m_root_command.empty()) {
|
||||
|
@ -148,45 +159,59 @@ void RootTheme::reconfigTheme() {
|
|||
// 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());
|
||||
// get the pixmap, force update of pixmap (needed if this is the first time)
|
||||
FbTk::FbPixmap root(FbTk::FbPixmap::getRootPixmap(screenNum(), true));
|
||||
|
||||
// render text
|
||||
static const char warning_msg[] =
|
||||
_FBTEXT(Common, BackgroundWarning,
|
||||
"There is no background option specified in this style."
|
||||
" Please consult the manual or read the FAQ.",
|
||||
"Background missing warning");
|
||||
|
||||
// if there is no root background pixmap...do nothing
|
||||
if (root.drawable() == None) {
|
||||
FbCommands::ExecuteCmd cmd("fbsetroot -solid darkgreen", screenNum());
|
||||
// wait for command to finish
|
||||
waitpid(cmd.run(), NULL, 0);
|
||||
// pixmap setting done. Force update of pixmaps
|
||||
root = FbTk::FbPixmap::getRootPixmap(screenNum(), true);
|
||||
|
||||
// The command could fail and not set the background...
|
||||
// so if the drawable is still none then just dont do anything more
|
||||
// but we still output warning msg to the console/log
|
||||
if (root.drawable() == None) {
|
||||
cerr<<"Fluxbox: "<<warning_msg<<endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 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());
|
||||
|
||||
_FB_USES_NLS;
|
||||
|
||||
FbTk::GContext gc(root);
|
||||
|
||||
// fill background color
|
||||
// fill rectangle
|
||||
gc.setForeground(FbTk::Color("black", screenNum()));
|
||||
root.fillRectangle(gc.gc(),
|
||||
0, 0,
|
||||
root.width(), root.height());
|
||||
FbTk::Font font;
|
||||
root.fillRectangle(gc.gc(), 0, 0,
|
||||
font.textWidth(warning_msg, strlen(warning_msg)) + 4,
|
||||
font.height() + 4);
|
||||
// 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
|
||||
|
||||
font.drawText(root, screenNum(), gc.gc(),
|
||||
warning_msg, strlen(warning_msg),
|
||||
2, font.height() + 2); // added some extra pixels for better visibility
|
||||
// output same msg to the log
|
||||
cerr<<"Fluxbox: "<<warning_msg<<endl;
|
||||
|
||||
// reset background mark
|
||||
m_background_loaded = true;
|
||||
root.release(); // we dont want to destroy this pixmap
|
||||
|
||||
rootwin.clear();
|
||||
|
||||
} else {
|
||||
// handle background option in style
|
||||
std::string filename = m_background->filename();
|
||||
|
@ -215,28 +240,44 @@ void RootTheme::reconfigTheme() {
|
|||
exec.execute();
|
||||
|
||||
} else {
|
||||
// render normal texture
|
||||
// render normal texture with fbsetroot
|
||||
|
||||
// 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);
|
||||
|
||||
// Make sure the color strings are valid,
|
||||
// so we dont pass any `commands` that can be executed
|
||||
bool color_valid =
|
||||
FbTk::Color::validColorString(m_background->colorString().c_str(),
|
||||
screenNum());
|
||||
bool color_to_valid =
|
||||
FbTk::Color::validColorString(m_background->colorToString().c_str(),
|
||||
screenNum());
|
||||
|
||||
std::string options;
|
||||
if (color_valid)
|
||||
options += "-foreground '" + m_background->colorString() + "' ";
|
||||
if (color_to_valid)
|
||||
options += "-background '" + m_background->colorToString() + "' ";
|
||||
|
||||
if ((*m_background)->type() & FbTk::Texture::SOLID && color_valid)
|
||||
options += "-solid '" + m_background->colorString() + "' ";
|
||||
|
||||
if ((*m_background)->type() & FbTk::Texture::GRADIENT) {
|
||||
|
||||
if (color_valid)
|
||||
options += "-from '" + m_background->colorString() + "' ";
|
||||
if (color_to_valid)
|
||||
options += "-to '" + m_background->colorToString() + "' ";
|
||||
|
||||
options += "-gradient '" + m_background->options() + "'";
|
||||
}
|
||||
|
||||
std::string commandargs = "fbsetroot " + options;
|
||||
|
||||
FbCommands::ExecuteCmd exec(commandargs, screenNum());
|
||||
exec.execute();
|
||||
}
|
||||
|
||||
rootwin.clear();
|
||||
}
|
||||
|
||||
// clear root window
|
||||
rootwin.clear();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue