From faf043bef92338fe976e639e94d309764065b8b7 Mon Sep 17 00:00:00 2001 From: simonb Date: Sun, 7 May 2006 10:08:25 +0000 Subject: more utf8 changes, notably window titles --- ChangeLog | 5 +++++ src/Ewmh.cc | 37 +++++++++++++++++++++++++++++++++++-- src/Ewmh.hh | 6 +++++- src/FbTk/FbString.cc | 8 ++++++++ src/FbTk/FbString.hh | 4 ---- src/FbTk/FbWindow.cc | 30 +++++++++++++++++++++++------- src/Screen.cc | 3 ++- src/WinClient.cc | 18 ++++++++++++++++++ src/WinClient.hh | 7 +++++-- src/WinClientUtil.cc | 8 ++++---- src/Workspace.cc | 3 ++- src/WorkspaceNameTool.cc | 4 ++-- src/fluxbox.cc | 2 +- 13 files changed, 110 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6acabdc..4774eab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 6bcd3e6..ea23a22 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -189,6 +189,15 @@ void Ewmh::initForScreen(BScreen &screen) { 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 @@ void Ewmh::setupFrame(FluxboxWindow &win) { &ret_type, &fmt, &nitems, &bytes_after, (unsigned char **) &data) && data) { unsigned int desktop = static_cast(*data); - if (desktop == -1 && !win.isStuck()) + if (desktop == (unsigned int)(-1) && !win.isStuck()) win.stick(); else win.setWorkspace(desktop); @@ -433,11 +442,21 @@ void Ewmh::updateWorkspaceNames(BScreen &screen) { 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 @@ void Ewmh::createAtoms() { 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 @@ void Ewmh::updateStrut(WinClient &winclient) { } } + + void Ewmh::updateActions(FluxboxWindow &win) { /* From Extended Window Manager Hints, draft 1.3: @@ -1151,3 +1183,4 @@ void Ewmh::clearState(FluxboxWindow &win) { void Ewmh::saveState(FluxboxWindow &win, WindowState *state) { m_savedstate[&win] = state; } + diff --git a/src/Ewmh.hh b/src/Ewmh.hh index 497665a..5c336e5 100644 --- a/src/Ewmh.hh +++ b/src/Ewmh.hh @@ -22,6 +22,7 @@ // $Id$ #include "AtomHandler.hh" +#include "FbTk/FbString.hh" #include #include @@ -101,7 +102,8 @@ private: 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, @@ -147,4 +149,6 @@ private: void clearState(FluxboxWindow &win); void saveState(FluxboxWindow &win, WindowState *state); + FbTk::FbString getUTF8Property(Atom property); + }; diff --git a/src/FbTk/FbString.cc b/src/FbTk/FbString.cc index a88b237..6c5ffbb 100644 --- a/src/FbTk/FbString.cc +++ b/src/FbTk/FbString.cc @@ -107,6 +107,14 @@ void shutdown() { @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) { diff --git a/src/FbTk/FbString.hh b/src/FbTk/FbString.hh index 371d4e9..011d47a 100644 --- a/src/FbTk/FbString.hh +++ b/src/FbTk/FbString.hh @@ -49,10 +49,6 @@ std::string FbStrToX(const FbString &src); 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 diff --git a/src/FbTk/FbWindow.cc b/src/FbTk/FbWindow.cc index 8f204b1..2c34fa1 100644 --- a/src/FbTk/FbWindow.cc +++ b/src/FbTk/FbWindow.cc @@ -23,6 +23,7 @@ #include "FbWindow.hh" #include "FbPixmap.hh" +#include "FbString.hh" #include "EventManager.hh" #include "Color.hh" @@ -450,28 +451,43 @@ void FbWindow::reparent(const FbWindow &parent, int x, int y, bool continuing) { 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 ""; 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 ""; - } else { + 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 { + // 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; } diff --git a/src/Screen.cc b/src/Screen.cc index 0609cd4..626b296 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -75,6 +75,7 @@ #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 @@ void BScreen::updateAvailableWorkspaceArea() { } void BScreen::addWorkspaceName(const char *name) { - m_workspace_names.push_back(name); + m_workspace_names.push_back(FbTk::FbStringUtil::LocaleStrToFb(name)); } diff --git a/src/WinClient.cc b/src/WinClient.cc index 056013a..891dc26 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -69,6 +69,8 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb 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 @@ void WinClient::updateTitle() { // 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; diff --git a/src/WinClient.hh b/src/WinClient.hh index aaaf111..870de6a 100644 --- a/src/WinClient.hh +++ b/src/WinClient.hh @@ -27,9 +27,9 @@ #include "Window.hh" #include "Subject.hh" #include "FbWindow.hh" +#include "FbTk/FbString.hh" #include -#include class BScreen; class Strut; @@ -64,7 +64,9 @@ public: 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 @@ private: 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; diff --git a/src/WinClientUtil.cc b/src/WinClientUtil.cc index 112360d..a6460a2 100644 --- a/src/WinClientUtil.cc +++ b/src/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 @@ void maxSize(const FluxboxWindow::ClientList &clients, 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; } diff --git a/src/Workspace.cc b/src/Workspace.cc index 343772a..c8650ca 100644 --- a/src/Workspace.cc +++ b/src/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 @@ void Workspace::setName(const std::string &name) { _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(); diff --git a/src/WorkspaceNameTool.cc b/src/WorkspaceNameTool.cc index 99d6854..3f66298 100644 --- a/src/WorkspaceNameTool.cc +++ b/src/WorkspaceNameTool.cc @@ -90,7 +90,7 @@ unsigned int WorkspaceNameTool::width() const { 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 @@ unsigned int WorkspaceNameTool::height() const { 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 diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 48b67bf..fd50392 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -1479,7 +1479,7 @@ void Fluxbox::save_rc() { 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(","); -- cgit v0.11.2