all repos — fluxbox @ faf043bef92338fe976e639e94d309764065b8b7

custom fork of the fluxbox windowmanager

more utf8 changes, notably window titles
simonb simonb
commit

faf043bef92338fe976e639e94d309764065b8b7

parent

ac098b4d0f0640b2997ff674a5c1b3447b6ba09a

M ChangeLogChangeLog

@@ -1,6 +1,11 @@

(Format: Year/Month/Day) Changes for 0.9.16: *06/05/07: + * Handle EMWH window and icon titles, plus localise workspace names (Simon) + - FbTk::FbWindow::textProperty now handles utf8 type, and always + returns UTF-8 encoded strings (for internal use) + Ewmh.hh/cc Screen.cc WinClient.hh/cc WinClientUtil.cc Workspace.cc + WorkspaceNameTool.cc fluxbox.cc FbTk/... FbString.hh/cc FbWindow.cc * Handle UTF-8 strings properly (Simon) - still need to integrate EWMH strings properly (they are utf8) - still need to fix up TextBox
M src/Ewmh.ccsrc/Ewmh.cc

@@ -189,6 +189,15 @@ }

void Ewmh::setupClient(WinClient &winclient) { updateStrut(winclient); + + FbTk::FbString newtitle = winclient.textProperty(m_net_wm_name); + if (!newtitle.empty()) { + winclient.setTitle(newtitle); + } + newtitle = winclient.textProperty(m_net_wm_icon_name); + if (!newtitle.empty()) { + winclient.setIconTitle(newtitle); + } } void Ewmh::setupFrame(FluxboxWindow &win) {

@@ -268,7 +277,7 @@ if (win.winClient().property(m_net_wm_desktop, 0, 1, False, XA_CARDINAL,

&ret_type, &fmt, &nitems, &bytes_after, (unsigned char **) &data) && data) { unsigned int desktop = static_cast<long>(*data); - if (desktop == -1 && !win.isStuck()) + if (desktop == (unsigned int)(-1) && !win.isStuck()) win.stick(); else win.setWorkspace(desktop);

@@ -433,11 +442,21 @@ memset(names[i], 0, workspacenames[i].size());

strcpy(names[i], workspacenames[i].c_str()); } +#ifdef X_HAVE_UTF8_STRING + Xutf8TextListToTextProperty(FbTk::App::instance()->display(), + names, number_of_desks, XUTF8StringStyle, &text); + XSetTextProperty(FbTk::App::instance()->display(), screen.rootWindow().window(), + &text, m_net_desktop_names); + + XFree(text.value); + +#else if (XStringListToTextProperty(names, number_of_desks, &text)) { XSetTextProperty(FbTk::App::instance()->display(), screen.rootWindow().window(), &text, m_net_desktop_names); XFree(text.value); } +#endif for (size_t i = 0; i < number_of_desks; i++) delete [] names[i];

@@ -810,7 +829,17 @@ bool Ewmh::propertyNotify(WinClient &winclient, Atom the_property) {

if (the_property == m_net_wm_strut) { updateStrut(winclient); return true; - } + } else if (the_property == m_net_wm_name) { + FbTk::FbString newtitle = winclient.textProperty(the_property); + if (!newtitle.empty()) + winclient.setTitle(newtitle); + return true; + } else if (the_property == m_net_wm_icon_name) { + FbTk::FbString newtitle = winclient.textProperty(the_property); + if (!newtitle.empty()) + winclient.setIconTitle(newtitle); + return true; + } return false; }

@@ -841,6 +870,7 @@ m_net_wm_moveresize = XInternAtom(disp, "_NET_WM_MOVERESIZE", False);

m_net_properties = XInternAtom(disp, "_NET_PROPERTIES", False); m_net_wm_name = XInternAtom(disp, "_NET_WM_NAME", False); + m_net_wm_icon_name = XInternAtom(disp, "_NET_WM_ICON_NAME", False); m_net_wm_desktop = XInternAtom(disp, "_NET_WM_DESKTOP", False); // type atoms

@@ -1017,6 +1047,8 @@ winclient.screen().updateAvailableWorkspaceArea();

} } + + void Ewmh::updateActions(FluxboxWindow &win) { /* From Extended Window Manager Hints, draft 1.3:

@@ -1151,3 +1183,4 @@

void Ewmh::saveState(FluxboxWindow &win, WindowState *state) { m_savedstate[&win] = state; } +
M src/Ewmh.hhsrc/Ewmh.hh

@@ -22,6 +22,7 @@

// $Id$ #include "AtomHandler.hh" +#include "FbTk/FbString.hh" #include <X11/Xatom.h> #include <vector>

@@ -101,7 +102,8 @@ // root window messages

Atom m_net_close_window, m_net_wm_moveresize; // application window properties - Atom m_net_properties, m_net_wm_name, m_net_wm_desktop, + Atom m_net_properties, m_net_wm_name, m_net_wm_icon_name, + m_net_wm_desktop, // types m_net_wm_window_type, m_net_wm_window_type_dock,

@@ -146,5 +148,7 @@

WindowState *getState(FluxboxWindow &win); void clearState(FluxboxWindow &win); void saveState(FluxboxWindow &win, WindowState *state); + + FbTk::FbString getUTF8Property(Atom property); };
M src/FbTk/FbString.ccsrc/FbTk/FbString.cc

@@ -107,6 +107,14 @@ @param msg text to be converted, **NOT** necessarily NULL terminated

@param size number of BYTES to convert @return the recoded string, or 0 on failure */ + +/** + --NOTE-- + In the "C" locale, this will strip any high-bit characters + because C means 7-bit ASCII charset. If you don't want this + then you need to set your locale to something UTF-8, OR something + ISO8859-1. +*/ std::string recode(iconv_t cd, const std::string &in) {
M src/FbTk/FbString.hhsrc/FbTk/FbString.hh

@@ -49,10 +49,6 @@ /// Handle thislocale string encodings (strings coming from userspace)

FbString LocaleStrToFb(const std::string &src); std::string FbStrToLocale(const FbString &src); -// essentially NO-OP -inline FbString UTF8StrToFb(const std::string &src) { return src; } -inline std::string FbStrToUTF8(const FbString &src) { return src; } - bool haveUTF8(); } // namespace FbStringUtil
M src/FbTk/FbWindow.ccsrc/FbTk/FbWindow.cc

@@ -23,6 +23,7 @@ // $Id$

#include "FbWindow.hh" #include "FbPixmap.hh" +#include "FbString.hh" #include "EventManager.hh" #include "Color.hh"

@@ -450,9 +451,11 @@ }

std::string FbWindow::textProperty(Atom property) const { XTextProperty text_prop; - char ** stringlist; + char ** stringlist = 0; int count; std::string ret; + + static Atom m_utf8string = XInternAtom(display(), "UTF8_STRING", False); if (XGetTextProperty(display(), window(), &text_prop, property) == 0) return "";

@@ -460,18 +463,31 @@

if (text_prop.value == 0 || text_prop.nitems == 0) return ""; - if (text_prop.encoding != XA_STRING) { - // still returns a "StringList" despite the different name - if (XmbTextPropertyToTextList(display(), &text_prop, &stringlist, &count) == 0 || count == 0) + if (text_prop.encoding == XA_STRING) { + if (XTextPropertyToStringList(&text_prop, &stringlist, &count) == 0 || count == 0) + return ""; + ret = FbStringUtil::XStrToFb(stringlist[0]); + } else if (text_prop.encoding == m_utf8string && text_prop.format == 8) { +#ifdef X_HAVE_UTF8_STRING + Xutf8TextPropertyToTextList(display(), &text_prop, &stringlist, &count); + if (count == 0) + return ""; +#else + if (XTextPropertyToStringList(&text_prop, &stringlist, &count) == 0 || count == 0) return ""; +#endif + ret = stringlist[0]; } else { - if (XTextPropertyToStringList(&text_prop, &stringlist, &count) == 0 || count == 0) + // still returns a "StringList" despite the different name + if (XmbTextPropertyToTextList(display(), &text_prop, &stringlist, &count) == 0 || count == 0) return ""; + ret = FbStringUtil::LocaleStrToFb(stringlist[0]); } - ret = stringlist[0]; - XFreeStringList(stringlist); + // they all use stringlist + if (stringlist) + XFreeStringList(stringlist); return ret; }
M src/Screen.ccsrc/Screen.cc

@@ -75,6 +75,7 @@ #include "FbTk/EventManager.hh"

#include "FbTk/Transparent.hh" #include "FbTk/Select2nd.hh" #include "FbTk/Compose.hh" +#include "FbTk/FbString.hh" //use GNU extensions #ifndef _GNU_SOURCE

@@ -1459,7 +1460,7 @@ m_workspace_area_sig.notify();

} void BScreen::addWorkspaceName(const char *name) { - m_workspace_names.push_back(name); + m_workspace_names.push_back(FbTk::FbStringUtil::LocaleStrToFb(name)); }
M src/WinClient.ccsrc/WinClient.cc

@@ -69,6 +69,8 @@ send_close_message(false),

m_win_gravity(0), m_title(""), m_icon_title(""), m_class_name(""), m_instance_name(""), + m_title_override(false), + m_icon_title_override(false), m_blackbox_hint(0), m_mwm_hint(0), m_focus_mode(F_PASSIVE),

@@ -342,10 +344,26 @@ // - why other windowmanagers (pekwm/pwm3/openbox etc) are

// also influenced // // the limitation to 512 chars only avoids running in that trap + if (m_title_override) + return; + m_title = string(Xutil::getWMName(window()), 0, 512); } +void WinClient::setTitle(FbTk::FbString &title) { + m_title = title; + m_title_override = true; +} + +void WinClient::setIconTitle(FbTk::FbString &icon_title) { + m_icon_title = icon_title; + m_icon_title_override = true; +} + void WinClient::updateIconTitle() { + if (m_icon_title_override) + return; + XTextProperty text_prop; char **list = 0; int num = 0;
M src/WinClient.hhsrc/WinClient.hh

@@ -27,9 +27,9 @@

#include "Window.hh" #include "Subject.hh" #include "FbWindow.hh" +#include "FbTk/FbString.hh" #include <X11/Xutil.h> -#include <string> class BScreen; class Strut;

@@ -64,7 +64,9 @@ /// updates from wm class hints

void updateWMClassHint(); void updateWMProtocols(); - + // override the title with this + void setTitle(FbTk::FbString &title); + void setIconTitle(FbTk::FbString &icon_title); void updateTitle(); void updateIconTitle(); /// updates transient window information

@@ -198,6 +200,7 @@ int m_win_gravity;

std::string m_title, m_icon_title; std::string m_class_name, m_instance_name; + bool m_title_override, m_icon_title_override; FbTk::FbPixmap m_icon_pixmap; FbTk::FbPixmap m_icon_mask;
M src/WinClientUtil.ccsrc/WinClientUtil.cc

@@ -9,8 +9,8 @@ void maxSize(const FluxboxWindow::ClientList &clients,

unsigned int &max_width, unsigned int &max_height) { FluxboxWindow::ClientList::const_iterator it = clients.begin(); FluxboxWindow::ClientList::const_iterator it_end = clients.end(); - max_width = ~0; // unlimited - max_height = ~0; // unlimited + max_width = (unsigned int) ~0; // unlimited + max_height = (unsigned int) ~0; // unlimited for (; it != it_end; ++it) { // special case for max height/width == 0 // 0 indicates unlimited size, so we skip them

@@ -21,9 +21,9 @@ if ((*it)->maxWidth() != 0)

max_width = std::min( (*it)->maxWidth(), max_width ); } - if (max_width == ~0) + if (max_width == (unsigned int) ~0) max_width = 0; - if (max_height == ~0) + if (max_height == (unsigned int) ~0) max_height = 0; }
M src/Workspace.ccsrc/Workspace.cc

@@ -38,6 +38,7 @@

#include "FbTk/I18n.hh" #include "FbTk/MenuItem.hh" #include "FbTk/StringUtil.hh" +#include "FbTk/FbString.hh" // use GNU extensions #ifndef _GNU_SOURCE

@@ -376,7 +377,7 @@ sprintf(tname,

_FBTEXT(Workspace, DefaultNameFormat, "Workspace %d", "Default workspace names, with a %d for the workspace number"), m_id + 1); //m_id starts at 0 - m_name = tname; + m_name = FbTk::FbStringUtil::LocaleStrToFb(tname); } screen().updateWorkspaceNamesAtom();
M src/WorkspaceNameTool.ccsrc/WorkspaceNameTool.cc

@@ -90,7 +90,7 @@ const BScreen::Workspaces& workspaces = m_screen.getWorkspacesList();

BScreen::Workspaces::const_iterator it; for (it = workspaces.begin(); it != workspaces.end(); it++) { const std::string &name = (*it)->name(); - max_size = std::max(m_theme.font().textWidth(name.c_str(), name.size()), + max_size = std::max(m_theme.font().textWidth(name, name.size()), max_size); } // so align text dont cut the last character

@@ -108,7 +108,7 @@ const BScreen::Workspaces& workspaces = m_screen.getWorkspacesList();

BScreen::Workspaces::const_iterator it; for (it = workspaces.begin(); it != workspaces.end(); it++) { const std::string &name = (*it)->name(); - max_size = std::max(m_theme.font().textWidth(name.c_str(), name.size()), + max_size = std::max(m_theme.font().textWidth(name, name.size()), max_size); } // so align text dont cut the last character
M src/fluxbox.ccsrc/fluxbox.cc

@@ -1479,7 +1479,7 @@ string workspaces_string(rc_string);

for (unsigned int workspace=0; workspace < screen->numberOfWorkspaces(); workspace++) { if (screen->getWorkspace(workspace)->name().size()!=0) - workspaces_string.append(screen->getWorkspace(workspace)->name()); + workspaces_string.append(FbTk::FbStringUtil::FbStrToLocale(screen->getWorkspace(workspace)->name())); else workspaces_string.append("Null"); workspaces_string.append(",");