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
127
src/RootTheme.cc
127
src/RootTheme.cc
|
@ -33,10 +33,16 @@
|
||||||
#include "FbTk/FileUtil.hh"
|
#include "FbTk/FileUtil.hh"
|
||||||
#include "FbTk/StringUtil.hh"
|
#include "FbTk/StringUtil.hh"
|
||||||
#include "FbTk/TextureRender.hh"
|
#include "FbTk/TextureRender.hh"
|
||||||
|
#include "FbTk/I18n.hh"
|
||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
class BackgroundItem: public FbTk::ThemeItem<FbTk::Texture> {
|
class BackgroundItem: public FbTk::ThemeItem<FbTk::Texture> {
|
||||||
|
@ -58,7 +64,8 @@ public:
|
||||||
string pixmap_name(FbTk::ThemeManager::instance().
|
string pixmap_name(FbTk::ThemeManager::instance().
|
||||||
resourceValue(m_name + ".pixmap", m_altname + ".Pixmap"));
|
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
|
// set default value if we failed to load colors
|
||||||
if (!(*this)->color().setFromString(color_name.c_str(),
|
if (!(*this)->color().setFromString(color_name.c_str(),
|
||||||
theme().screenNum()))
|
theme().screenNum()))
|
||||||
|
@ -87,8 +94,11 @@ public:
|
||||||
}
|
}
|
||||||
const std::string &filename() const { return m_filename; }
|
const std::string &filename() const { return m_filename; }
|
||||||
const std::string &options() const { return m_options; }
|
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:
|
private:
|
||||||
std::string m_filename, m_options;
|
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() {
|
void RootTheme::reconfigTheme() {
|
||||||
if (m_lock)
|
if (m_lock)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// if user specified background in the config then use it
|
// if user specified background in the config then use it
|
||||||
// instead of style background
|
// instead of style background
|
||||||
if (!m_root_command.empty()) {
|
if (!m_root_command.empty()) {
|
||||||
|
@ -148,45 +159,59 @@ void RootTheme::reconfigTheme() {
|
||||||
// notifies the user about it
|
// notifies the user about it
|
||||||
|
|
||||||
if (!m_background_loaded) {
|
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);
|
FbTk::GContext gc(root);
|
||||||
|
// fill rectangle
|
||||||
// fill background color
|
|
||||||
gc.setForeground(FbTk::Color("black", screenNum()));
|
gc.setForeground(FbTk::Color("black", screenNum()));
|
||||||
root.fillRectangle(gc.gc(),
|
FbTk::Font font;
|
||||||
0, 0,
|
root.fillRectangle(gc.gc(), 0, 0,
|
||||||
root.width(), root.height());
|
font.textWidth(warning_msg, strlen(warning_msg)) + 4,
|
||||||
|
font.height() + 4);
|
||||||
// text color
|
// text color
|
||||||
gc.setForeground(FbTk::Color("white", screenNum()));
|
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
|
// reset background mark
|
||||||
m_background_loaded = true;
|
m_background_loaded = true;
|
||||||
root.release(); // we dont want to destroy this pixmap
|
root.release(); // we dont want to destroy this pixmap
|
||||||
|
|
||||||
|
rootwin.clear();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// handle background option in style
|
// handle background option in style
|
||||||
std::string filename = m_background->filename();
|
std::string filename = m_background->filename();
|
||||||
|
@ -215,28 +240,44 @@ void RootTheme::reconfigTheme() {
|
||||||
exec.execute();
|
exec.execute();
|
||||||
|
|
||||||
} else {
|
} 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear root window
|
|
||||||
rootwin.clear();
|
rootwin.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue