all repos — fluxbox @ 690d926ac444243611cd875fb84fabb4e6db2cf2

custom fork of the fluxbox windowmanager

introduced FbTk::BidiString

a 'BidiString' holds both the logical content and the visual reordered
version of the content of a string. this helps to reduce the number of
calls to reorder the string before drawing it (as introduced in the patch
from Ken Bloom) and to be more consistent in menus and textboxes (drawing
cursors and underlining text).
Mathias Gumz akira at fluxbox dot org
commit

690d926ac444243611cd875fb84fabb4e6db2cf2

parent

1e8fe2bc14856fa16508686a28a85e72cb0e422c

M src/ClientMenu.ccsrc/ClientMenu.cc

@@ -36,7 +36,7 @@

class ClientMenuItem: public FbTk::MenuItem { public: ClientMenuItem(Focusable &client, ClientMenu &menu): - FbTk::MenuItem(client.title().c_str(), menu), + FbTk::MenuItem(client.title(), menu), m_client(client) { m_signals.join(client.titleSig(), FbTk::MemFunSelectArg1(menu, &ClientMenu::titleChanged));

@@ -65,7 +65,7 @@ parent->hide();

} } - const std::string &label() const { return m_client.title(); } + const FbTk::BiDiString &label() const { return m_client.title(); } const FbTk::PixmapWithMask *icon() const { return m_client.screen().clientMenuUsePixmap() ? &m_client.icon() : 0; }
M src/ClientPattern.ccsrc/ClientPattern.cc

@@ -341,13 +341,13 @@ m_terms.push_back(term);

return true; } -string ClientPattern::getProperty(WinProperty prop, const Focusable &client) { +FbTk::FbString ClientPattern::getProperty(WinProperty prop, const Focusable &client) { // we need this for some of the window properties const FluxboxWindow *fbwin = client.fbwindow(); switch (prop) { case TITLE: - return client.title(); + return client.title().logical(); break; case CLASS: return client.getWMClassClass();
M src/ClockTool.ccsrc/ClockTool.cc

@@ -93,7 +93,7 @@

class ClockMenuItem: public FbTk::MenuItem { public: explicit ClockMenuItem(ClockTool &tool): - FbTk::MenuItem(""), m_tool(tool) { + FbTk::MenuItem(FbTk::BiDiString("")), m_tool(tool) { setClockModeLabel(); setCloseOnClick(false);

@@ -160,7 +160,7 @@ ClockTool::ClockTool(const FbTk::FbWindow &parent,

FbTk::ThemeProxy<ToolTheme> &theme, BScreen &screen, FbTk::Menu &menu): ToolbarItem(ToolbarItem::FIXED), - m_button(parent, theme->font(), ""), + m_button(parent, theme->font(), FbTk::BiDiString("")), m_theme(theme), m_screen(screen), m_pixmap(0),

@@ -243,7 +243,7 @@ // + 2 to make the entire text fit inside

// we only replace numbers with zeros because everything else should be // relatively static. If we replace all text with zeros then widths of // proportional fonts with some strftime formats will be considerably off. - std::string text(m_button.text()); + FbTk::FbString text(m_button.text().logical()); int textlen = text.size(); for (int i=0; i < textlen; ++i) {

@@ -255,7 +255,7 @@

unsigned int new_width = m_button.width(); unsigned int new_height = m_button.height(); translateSize(orientation(), new_width, new_height); - new_width = m_theme->font().textWidth(text, text.size()); + new_width = m_theme->font().textWidth(text.c_str(), text.size()); translateSize(orientation(), new_width, new_height); if (new_width != m_button.width() || new_height != m_button.height()) { resize(new_width, new_height);

@@ -296,7 +296,7 @@ time_string_len = strftime(time_string, 255, m_timeformat->c_str(), time_type);

if( time_string_len == 0) return; std::string text = m_stringconvertor.recode(time_string); - if (m_button.text() == text) + if (m_button.text().logical() == text) return; m_button.setText(text);
M src/Ewmh.ccsrc/Ewmh.cc

@@ -131,7 +131,7 @@

// actually there is some data in _NET_WM_ICON nr_icon_data = nr_bytes_left / sizeof(CARD32); - fbdbg << "extractNetWmIcon: " << winclient.title() << "\n"; + fbdbg << "extractNetWmIcon: " << winclient.title().logical() << "\n"; fbdbg << "nr_icon_data: " << nr_icon_data << "\n"; // read all the icons stored in _NET_WM_ICON

@@ -164,7 +164,7 @@ width = raw_data[i++];

if (width >= nr_icon_data) { fbdbg << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON width (" - << width << ") for " << winclient.title() << "\n"; + << width << ") for " << winclient.title().logical() << "\n"; break; }

@@ -172,7 +172,7 @@ height = raw_data[i++];

if (height >= nr_icon_data) { fbdbg << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON height (" - << height << ") for " << winclient.title() << "\n"; + << height << ") for " << winclient.title().logical() << "\n"; break; }

@@ -180,7 +180,8 @@

// strange values stored in the NETWM_ICON if (i + width * height > nr_icon_data) { fbdbg << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON dimensions (" - << width << "x" << height << ")for " << winclient.title() << "\n"; + + << width << "x" << height << ")for " << winclient.title().logical() << "\n"; break; }
M src/FbCommands.ccsrc/FbCommands.cc

@@ -364,7 +364,7 @@ }

void ShowCustomMenuCmd::reload() { m_menu->removeAll(); - m_menu->setLabel(""); + m_menu->setLabel(FbTk::BiDiString("")); MenuCreator::createFromFile(custom_menu_file, *m_menu.get(), m_menu->reloadHelper()); }
M src/FbTk/FbString.ccsrc/FbTk/FbString.cc

@@ -62,8 +62,86 @@ using std::cerr;

using std::endl; #endif // DEBUG +namespace { + +#ifdef HAVE_FRIBIDI +FbTk::FbString makeVisualFromLogical(const FbTk::FbString& src) { + + FriBidiCharType base = FRIBIDI_TYPE_N; + + // reuse allocated memory for reencoding / reordering + static std::vector<FriBidiChar> us; + static std::vector<FriBidiChar> out_us; + static FbTk::FbString result; + + const size_t S = src.size() + 1; + const size_t S4 = S * 4; + + if (us.capacity() < S) + us.reserve(S); + if (out_us.capacity() < S) + out_us.reserve(S); + if (result.capacity() < S4) + result.reserve(S4); + + us.resize(S); + FriBidiStrIndex len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, + const_cast<char*>(src.c_str()), S - 1, + &us[0]); + + out_us.resize(S); + fribidi_log2vis(&us[0], len, &base, &out_us[0], NULL, NULL, NULL); + + result.resize(S4); + len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, &out_us[0], len, &result[0]); + result.resize(len); // trim to currently used chars + + return result; +} + +#endif + +} // end of anonymous namespace + + namespace FbTk { + +BiDiString::BiDiString(const FbString& logical) +#ifdef HAVE_FRIBIDI + : m_visual_dirty(false) +#endif +{ + if (!logical.empty()) + setLogical(logical); +} + +const FbString& BiDiString::setLogical(const FbString& logical) { + m_logical = logical; +#if HAVE_FRIBIDI + if (m_logical.empty()) { + m_visual_dirty = false; + m_visual.clear(); + } else { + m_visual_dirty = true; + } +#endif +} + +const FbString& BiDiString::visual() const { +#if HAVE_FRIBIDI + if (m_visual_dirty) { + m_visual = ::makeVisualFromLogical(logical()); + } + m_visual_dirty = false; + return m_visual; +#else + return m_logical; +#endif +} + + + namespace FbStringUtil { enum ConvType { FB2X = 0, X2FB, LOCALE2FB, FB2LOCALE, CONVSIZE };

@@ -128,7 +206,6 @@

-#ifdef HAVE_ICONV /** Recodes the text from one encoding to another assuming cd is correct

@@ -137,7 +214,9 @@ @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 */ +string recode(iconv_t cd, const string &in) { +#ifdef HAVE_ICONV /** --NOTE-- In the "C" locale, this will strip any high-bit characters

@@ -145,8 +224,6 @@ 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. */ -string recode(iconv_t cd, - const string &in) { // If empty message, yes this can happen, return if (in.empty())

@@ -163,18 +240,18 @@

size_t inbytesleft = insize; size_t outbytesleft = outsize; +#ifdef HAVE_CONST_ICONV + const char* in_ptr = in.data(); +#else char * in_ptr = const_cast<char *>(in.data()); +#endif size_t result = (size_t)(-1); bool again = true; while (again) { again = false; -#ifdef HAVE_CONST_ICONV - result = iconv(cd, (const char**)(&in_ptr), &inbytesleft, &out_ptr, &outbytesleft); -#else result = iconv(cd, &in_ptr, &inbytesleft, &out_ptr, &outbytesleft); -#endif // HAVE_CONST_ICONV if (result == (size_t)(-1)) { switch(errno) {

@@ -213,13 +290,10 @@ if (out)

free(out); return ret; -} #else -string recode(int cd, - const string &str) { return str; -} #endif // HAVE_ICONV +} FbString XStrToFb(const string &src) { return recode(iconv_convs[X2FB], src);

@@ -249,58 +323,18 @@ return false;

} -#ifdef HAVE_FRIBIDI - -FbString BidiLog2Vis (const FbString& src) { - - FriBidiCharType base = FRIBIDI_TYPE_N; - - // reuse allocated memory for reencoding / reordering - static std::vector<FriBidiChar> us; - static std::vector<FriBidiChar> out_us; - static FbString result; - - const size_t S = src.size() + 1; - const size_t S4 = S * 4; - - if (us.capacity() < S) - us.reserve(S); - if (out_us.capacity() < S) - out_us.reserve(S); - if (result.capacity() < S4) - result.reserve(S4); - - us.resize(S); - FriBidiStrIndex len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, - const_cast<char*>(src.c_str()), S - 1, - &us[0]); - - out_us.resize(S); - fribidi_log2vis(&us[0], len, &base, &out_us[0], NULL, NULL, NULL); - - result.resize(S4); - len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, &out_us[0], len, &result[0]); - result.resize(len); // trim to currently used chars - - return result; -} - -#endif - } // end namespace StringUtil -StringConvertor::StringConvertor(EncodingTarget target): #ifdef HAVE_ICONV - m_iconv((iconv_t)(-1)) { +StringConvertor::StringConvertor(EncodingTarget target) : m_iconv((iconv_t)(-1)) { if (target == ToLocaleStr) m_destencoding = FbStringUtil::locale_codeset; else m_destencoding = "UTF-8"; } #else - m_iconv(-1) {} +StringConvertor::StringConvertor(EncodingTarget target) { } #endif - StringConvertor::~StringConvertor() { #ifdef HAVE_ICONV

@@ -329,11 +363,19 @@ return false;

#endif } -string StringConvertor::recode(const string &src) { +FbString StringConvertor::recode(const string &src) { #ifdef HAVE_ICONV return FbStringUtil::recode(m_iconv, src); #else return src; +#endif +} + +void StringConvertor::reset() { +#ifdef HAVE_ICONV + if (m_iconv != ((iconv_t)-1)) + iconv_close(m_iconv); + m_iconv = ((iconv_t)(-1)); #endif }
M src/FbTk/FbString.hhsrc/FbTk/FbString.hh

@@ -36,6 +36,25 @@ // Use this type for things converted to our internal encoding (UTF-8)

// (or just plain whatever for now if no utf-8 available) typedef std::string FbString; +class BiDiString { + +public: + + BiDiString(const FbString& logical = FbString()); + + const FbString& logical() const { return m_logical; } + const FbString& visual() const; + + const FbString& setLogical(const FbString& logical); + +private: + FbString m_logical; +#ifdef HAVE_FRIBIDI + mutable FbString m_visual; + mutable bool m_visual_dirty; +#endif +}; + namespace FbStringUtil { void init();

@@ -52,11 +71,6 @@ /// Handle thislocale string encodings (strings coming from userspace)

FbString LocaleStrToFb(const std::string &src); std::string FbStrToLocale(const FbString &src); -#ifdef HAVE_FRIBIDI -/// Make Bidi -FbString BidiLog2Vis (const FbString& src); -#endif - bool haveUTF8(); } // namespace FbStringUtil

@@ -70,23 +84,14 @@ StringConvertor(EncodingTarget target);

~StringConvertor(); bool setSource(const std::string &encoding); - void reset() { -#ifdef HAVE_ICONV - if (m_iconv != ((iconv_t)-1)) - iconv_close(m_iconv); - m_iconv = ((iconv_t)(-1)); -#endif - } + void reset(); - std::string recode(const std::string &src); + FbString recode(const FbString &src); private: #ifdef HAVE_ICONV iconv_t m_iconv; -#else - int m_iconv; #endif - std::string m_destencoding; };
M src/FbTk/Font.ccsrc/FbTk/Font.cc

@@ -247,14 +247,8 @@

return false; } -unsigned int Font::textWidth(const FbString &text, unsigned int size) const { -#ifdef HAVE_FRIBIDI - const FbString visualOrder(FbTk::FbStringUtil::BidiLog2Vis(text)); -#else - const FbString &visualOrder = text; -#endif - - return m_fontimp->textWidth(visualOrder, size); +unsigned int Font::textWidth(const char* text, unsigned int size) const { + return m_fontimp->textWidth(text, size); } unsigned int Font::height() const {

@@ -274,34 +268,28 @@ return m_fontimp->validOrientation(orient);

} void Font::drawText(const FbDrawable &w, int screen, GC gc, - const FbString &text, size_t len, int x, int y, + const char* text, size_t len, int x, int y, Orientation orient) const { - if (text.empty() || len == 0) - return; -#ifdef HAVE_FRIBIDI - const FbString visualOrder(FbTk::FbStringUtil::BidiLog2Vis(text)); -#else - const FbString &visualOrder = text; -#endif - + if (!text || !*text || len == 0) + return; // draw "effects" first if (m_shadow) { FbTk::GContext shadow_gc(w); shadow_gc.setForeground(m_shadow_color); - m_fontimp->drawText(w, screen, shadow_gc.gc(), visualOrder, len, + m_fontimp->drawText(w, screen, shadow_gc.gc(), text, len, x + m_shadow_offx, y + m_shadow_offy, orient); } else if (m_halo) { FbTk::GContext halo_gc(w); halo_gc.setForeground(m_halo_color); - m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x + 1, y + 1, orient); - m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x - 1, y + 1, orient); - m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x - 1, y - 1, orient); - m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x + 1, y - 1, orient); + m_fontimp->drawText(w, screen, halo_gc.gc(), text, len, x + 1, y + 1, orient); + m_fontimp->drawText(w, screen, halo_gc.gc(), text, len, x - 1, y + 1, orient); + m_fontimp->drawText(w, screen, halo_gc.gc(), text, len, x - 1, y - 1, orient); + m_fontimp->drawText(w, screen, halo_gc.gc(), text, len, x + 1, y - 1, orient); } - m_fontimp->drawText(w, screen, gc, visualOrder, len, x, y, orient); + m_fontimp->drawText(w, screen, gc, text, len, x, y, orient); }
M src/FbTk/Font.hhsrc/FbTk/Font.hh

@@ -75,7 +75,11 @@ @param text text to check size

@param size length of text in bytes @return size of text in pixels */ - unsigned int textWidth(const FbString &text, unsigned int size) const; + unsigned int textWidth(const char* text, unsigned int size) const; + unsigned int textWidth(const BiDiString &text) const { + return textWidth(text.visual().c_str(), text.visual().size()); + } + unsigned int height() const; int ascent() const; int descent() const;

@@ -99,8 +103,14 @@ @param y position

@param rotate if the text should be drawn rotated (if it's rotated before) */ void drawText(const FbDrawable &w, int screen, GC gc, - const FbString &text, size_t len, + const char* text, size_t len, int x, int y, FbTk::Orientation orient = ROT0) const; + void drawText(const FbDrawable &w, int screen, GC gc, + const BiDiString &text, + int x, int y, FbTk::Orientation orient = ROT0) const { + drawText(w, screen, gc, text.visual().c_str(), text.visual().size(), x, y, orient); + } + bool hasShadow() const { return m_shadow; } bool hasHalo() const { return m_halo; }
M src/FbTk/FontImp.hhsrc/FbTk/FontImp.hh

@@ -40,8 +40,8 @@ class FontImp {

public: virtual ~FontImp() { } virtual bool load(const std::string &name) = 0; - virtual void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) = 0; - virtual unsigned int textWidth(const FbString &text, unsigned int size) const = 0; + virtual void drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient) = 0; + virtual unsigned int textWidth(const char* text, unsigned int len) const = 0; virtual bool validOrientation(FbTk::Orientation orient) { return orient == ROT0; } virtual int ascent() const = 0; virtual int descent() const = 0;
M src/FbTk/ITypeAheadable.hhsrc/FbTk/ITypeAheadable.hh

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

#ifndef FBTK_ITYPEAHEADABLE_HH #define FBTK_ITYPEAHEADABLE_HH -#include <string> +#include "FbString.hh" #ifdef HAVE_CCTYPE #include <cctype>
M src/FbTk/IntMenuItem.hhsrc/FbTk/IntMenuItem.hh

@@ -23,6 +23,7 @@ #ifndef FBTK_INTMENUITEM_HH

#define FBTK_INTMENUITEM_HH #include "MenuItem.hh" +#include "StringUtil.hh" namespace FbTk {

@@ -37,15 +38,6 @@ FbTk::MenuItem(label, host_menu), m_org_label(FbTk::MenuItem::label()),

m_max(max_val), m_min(min_val), m_res(res) { updateLabel(); setCloseOnClick(false); - } - - /* Utility, but doesn't get found in anonymous namespace? */ - std::string appendIntValue(const std::string &label, int value) { - char *buff = new char[label.size() + 16]; - sprintf(buff, "%s: %d", label.c_str(), value); - std::string ret(buff); - delete [] buff; - return ret; } void click(int button, int time, unsigned int mods) {

@@ -86,11 +78,11 @@ }

} void updateLabel() { - setLabel(appendIntValue(m_org_label, m_res)); + setLabel(m_org_label.logical() + ": " + FbTk::StringUtil::number2String(m_res)); } private: - std::string m_org_label; ///< original label + FbTk::BiDiString m_org_label; ///< original label const int m_max; ///< maximum value the integer can have const int m_min; ///< minimum value the integer can have Accessor<int> &m_res; ///< resource item to be changed
M src/FbTk/Menu.ccsrc/FbTk/Menu.cc

@@ -375,8 +375,7 @@ }

void Menu::updateMenu() { if (m_title_vis) { - menu.item_w = theme()->titleFont().textWidth(menu.label, - menu.label.size()); + menu.item_w = theme()->titleFont().textWidth(menu.label); menu.item_w += (theme()->bevelWidth() * 2); } else menu.item_w = 1;

@@ -669,8 +668,7 @@ void Menu::redrawTitle(FbDrawable &drawable) {

const FbTk::Font &font = theme()->titleFont(); int dx = theme()->bevelWidth(); - size_t len = menu.label.size(); - unsigned int l = font.textWidth(menu.label, len) + theme()->bevelWidth()*2; + unsigned int l = font.textWidth(menu.label) + theme()->bevelWidth()*2; switch (theme()->titleFontJustify()) { case FbTk::RIGHT:

@@ -686,10 +684,7 @@ }

// difference between height based on font, and style-set height int height_offset = theme()->titleHeight() - (font.height() + 2*theme()->bevelWidth()); - font.drawText(drawable, // drawable - screenNumber(), - theme()->titleTextGC().gc(), // graphic context - menu.label, len, // text string with length + font.drawText(drawable, screenNumber(), theme()->titleTextGC().gc(), menu.label, dx, font.ascent() + theme()->bevelWidth() + height_offset/2); // position }

@@ -795,7 +790,7 @@

return item_y; } -void Menu::setLabel(const FbString &labelstr) { +void Menu::setLabel(const FbTk::BiDiString &labelstr) { //make sure we don't send 0 to std::string menu.label = labelstr; reconfigure();
M src/FbTk/Menu.hhsrc/FbTk/Menu.hh

@@ -108,7 +108,7 @@ /// get input focus

void grabInputFocus(); virtual void reconfigure(); /// set label string - void setLabel(const FbString &labelstr); + void setLabel(const FbTk::BiDiString &labelstr); /// move menu to x,y virtual void move(int x, int y); virtual void updateMenu();

@@ -136,7 +136,7 @@ FbWindow &fbwindow() { return menu.window; }

const FbWindow &fbwindow() const { return menu.window; } FbWindow &titleWindow() { return menu.title; } FbWindow &frameWindow() { return menu.frame; } - const std::string &label() const { return menu.label; } + const FbTk::BiDiString &label() const { return menu.label; } int x() const { return menu.window.x(); } int y() const { return menu.window.y(); } unsigned int width() const { return menu.window.width(); }

@@ -225,7 +225,7 @@ struct _menu {

Pixmap frame_pixmap, title_pixmap, hilite_pixmap; FbTk::FbWindow window, frame, title; - std::string label; + FbTk::BiDiString label; int x_move, y_move, sublevels, persub, minsub, grab_x, grab_y; unsigned int frame_h, item_w;
M src/FbTk/MenuItem.ccsrc/FbTk/MenuItem.cc

@@ -52,14 +52,14 @@

int font_top = (height - theme->frameFont().height())/2; int underline_height = font_top + theme->frameFont().ascent() + 2; int bottom = height - bevelW - 1; - + text_y += bottom > underline_height ? underline_height : bottom; - int text_w = theme->frameFont().textWidth(m_label, m_label.size()); - // width of the searchstring - size = size > m_label.length() ? m_label.length() : size; - std::string search_string = m_label.substr(0,size); - int search_string_w = theme->frameFont().textWidth(search_string, size); + int text_w = theme->frameFont().textWidth(label()); + + const FbString& visual = m_label.visual(); + BiDiString search_string(FbString(visual, 0, size > visual.size() ? visual.size() : size)); + int search_string_w = theme->frameFont().textWidth(search_string); // pay attention to the text justification switch(theme->frameFontJustify()) {

@@ -144,7 +144,7 @@ }

} } - if (label().empty()) + if (label().logical().empty()) return; // text is background

@@ -156,8 +156,7 @@ //

// Text // int text_y = y, text_x = x; - - int text_w = theme->frameFont().textWidth(label(), label().size()); + int text_w = theme->frameFont().textWidth(label()); int height_offset = theme->itemHeight() - (theme->frameFont().height() + 2*theme->bevelWidth()); text_y = y + theme->bevelWidth() + theme->frameFont().ascent() + height_offset/2;

@@ -175,11 +174,7 @@ text_x = x + ((width + 1 - text_w) / 2);

break; } - theme->frameFont().drawText(draw, // drawable - theme->screenNum(), - tgc.gc(), - label().c_str(), label().size(), // text string and lenght - text_x, text_y); // position + theme->frameFont().drawText(draw, theme->screenNum(), tgc.gc(), label(), text_x, text_y); } GC gc = (highlight) ? theme->hiliteTextGC().gc() :

@@ -335,7 +330,7 @@

unsigned int MenuItem::width(const FbTk::ThemeProxy<MenuTheme> &theme) const { // textwidth + bevel width on each side of the text const unsigned int icon_width = height(theme); - const unsigned int normal = theme->frameFont().textWidth(label(), label().size()) + + const unsigned int normal = theme->frameFont().textWidth(label()) + 2 * (theme->bevelWidth() + icon_width); return m_icon.get() == 0 ? normal : normal + icon_width; }

@@ -349,9 +344,9 @@

} -void MenuItem::showSubmenu() { - if (submenu() != 0) - submenu()->show(); +void MenuItem::showSubmenu() { + if (submenu() != 0) + submenu()->show(); } } // end namespace FbTk
M src/FbTk/MenuItem.hhsrc/FbTk/MenuItem.hh

@@ -41,7 +41,7 @@ /// An interface for a menu item in Menu

class MenuItem : public FbTk::ITypeAheadable { public: MenuItem() - : m_label(""), + : m_label(BiDiString("")), m_menu(0), m_submenu(0), m_enabled(true),

@@ -49,7 +49,7 @@ m_selected(false),

m_close_on_click(true), m_toggle_item(false) { } - explicit MenuItem(const FbString &label) + explicit MenuItem(const BiDiString &label) : m_label(label), m_menu(0), m_submenu(0),

@@ -59,7 +59,7 @@ m_close_on_click(true),

m_toggle_item(false) { } - MenuItem(const FbString &label, Menu &host_menu) + MenuItem(const BiDiString &label, Menu &host_menu) : m_label(label), m_menu(&host_menu), m_submenu(0),

@@ -69,7 +69,7 @@ m_close_on_click(true),

m_toggle_item(false) { } /// create a menu item with a specific command to be executed on click - MenuItem(const FbString &label, RefCount<Command<void> > &cmd, Menu *menu = 0) + MenuItem(const BiDiString &label, RefCount<Command<void> > &cmd, Menu *menu = 0) : m_label(label), m_menu(menu), m_submenu(0),

@@ -80,7 +80,7 @@ m_close_on_click(true),

m_toggle_item(false) { } - MenuItem(const FbString &label, Menu *submenu, Menu *host_menu = 0) + MenuItem(const BiDiString &label, Menu *submenu, Menu *host_menu = 0) : m_label(label), m_menu(host_menu), m_submenu(submenu),

@@ -94,7 +94,7 @@

void setCommand(RefCount<Command<void> > &cmd) { m_command = cmd; } virtual void setSelected(bool selected) { m_selected = selected; } virtual void setEnabled(bool enabled) { m_enabled = enabled; } - virtual void setLabel(const FbString &label) { m_label = label; } + virtual void setLabel(const BiDiString &label) { m_label = label; } virtual void setToggleItem(bool val) { m_toggle_item = val; } void setCloseOnClick(bool val) { m_close_on_click = val; } void setIcon(const std::string &filename, int screen_num);

@@ -103,7 +103,7 @@ /**

@name accessors */ //@{ - virtual const std::string &label() const { return m_label; } + virtual const FbTk::BiDiString& label() const { return m_label; } virtual const PixmapWithMask *icon() const { return m_icon.get() ? m_icon->pixmap.get() : 0; }

@@ -115,7 +115,7 @@

// iType functions virtual void setIndex(int index) { m_index = index; } virtual int getIndex() { return m_index; } - const std::string &iTypeString() const { return m_label; } + const FbString &iTypeString() const { return m_label.visual(); } virtual void drawLine(FbDrawable &draw, const FbTk::ThemeProxy<MenuTheme> &theme, size_t size,

@@ -148,7 +148,7 @@ void setMenu(Menu &menu) { m_menu = &menu; }

Menu *menu() { return m_menu; } private: - FbString m_label; ///< label of this item + BiDiString m_label; ///< label of this item Menu *m_menu; ///< the menu we live in Menu *m_submenu; ///< a submenu, 0 if we don't have one RefCount<Command<void> > m_command; ///< command to be executed
M src/FbTk/MultiButtonMenuItem.ccsrc/FbTk/MultiButtonMenuItem.cc

@@ -26,14 +26,14 @@ #include "Command.hh"

namespace FbTk { -MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbString &label): +MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbTk::BiDiString &label): MenuItem(label), m_button_exe(0), m_buttons(buttons) { init(buttons); } -MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbString &label, Menu *submenu): +MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbTk::BiDiString &label, Menu *submenu): MenuItem(label, submenu), m_button_exe(0), m_buttons(buttons) {
M src/FbTk/MultiButtonMenuItem.hhsrc/FbTk/MultiButtonMenuItem.hh

@@ -30,8 +30,8 @@

/// Handles commands for the specified numbers of buttons class MultiButtonMenuItem: public FbTk::MenuItem { public: - MultiButtonMenuItem(int buttons, const FbString &label); - MultiButtonMenuItem(int buttons, const FbString &label, Menu *submenu); + MultiButtonMenuItem(int buttons, const FbTk::BiDiString& label); + MultiButtonMenuItem(int buttons, const FbTk::BiDiString& label, Menu *submenu); virtual ~MultiButtonMenuItem(); /// sets command to specified button void setCommand(int button, FbTk::RefCount<FbTk::Command<void> > &cmd);
M src/FbTk/TextBox.ccsrc/FbTk/TextBox.cc

@@ -75,7 +75,7 @@ TextBox::~TextBox() {

} -void TextBox::setText(const std::string &text) { +void TextBox::setText(const FbTk::BiDiString &text) { m_text = text; m_start_pos = 0; cursorEnd();

@@ -129,7 +129,9 @@ }

void TextBox::backspace() { if (m_start_pos || cursorPosition()) { - m_text.erase(m_start_pos + cursorPosition() - 1, 1); + FbString t = text(); + t.erase(m_start_pos + cursorPosition() - 1, 1); + m_text.setLogical(t); if (cursorPosition()) setCursorPosition(cursorPosition() - 1); else

@@ -140,23 +142,28 @@ }

void TextBox::deleteForward() { if (m_start_pos + m_cursor_pos < m_end_pos) { - m_text.erase(m_start_pos + m_cursor_pos, 1); + FbString t = text(); + t.erase(m_start_pos + m_cursor_pos, 1); + m_text.setLogical(t); adjustEndPos(); } } void TextBox::insertText(const std::string &val) { - m_text.insert(m_start_pos + cursorPosition(), val); + FbString t = text(); + t.insert(m_start_pos + cursorPosition(), val); + m_text.setLogical(t); m_cursor_pos += val.size(); m_end_pos += val.size(); - + adjustPos(); } void TextBox::killToEnd() { if (cursorPosition() >= 0 && cursorPosition() < static_cast<signed>(text().size())) { - m_text.erase(cursorPosition()); - setText(m_text); + FbString t = text(); + t.erase(cursorPosition()); + setText(t); } }

@@ -168,13 +175,13 @@ if (gc() == 0)

setGC(DefaultGC(FbTk::App::instance()->display(), screenNumber())); font().drawText(*this, screenNumber(), - gc(), - text().c_str() + m_start_pos, - m_end_pos - m_start_pos, + gc(), + m_text.visual().c_str() + m_start_pos, + m_end_pos - m_start_pos, 0, center_pos); // pos // draw cursor position - int cursor_pos = font().textWidth(text().c_str() + m_start_pos, m_cursor_pos) + 1; + int cursor_pos = font().textWidth(m_text.visual().c_str() + m_start_pos, m_cursor_pos) + 1; drawLine(gc(), cursor_pos, center_pos, cursor_pos, center_pos - font().height()); }

@@ -202,9 +209,7 @@ int delta = width();

int tmp = 0; for(i = m_start_pos; i <= m_end_pos; i++) { tmp = abs(static_cast<int> - (event.x - font(). - textWidth(m_text.c_str() + m_start_pos, - i - m_start_pos))); + (event.x - font().textWidth(m_text.visual().c_str() + m_start_pos, i - m_start_pos))); if (tmp < delta) { delta = tmp;

@@ -244,7 +249,7 @@ adjustPos();

} break; case XK_Right: - if (m_text.size() && m_cursor_pos < m_text.size()){ + if (!m_text.logical().empty() && m_cursor_pos < m_text.logical().size()){ unsigned int pos = findEmptySpaceRight(); if (pos > m_start_pos) pos -= m_start_pos;

@@ -264,7 +269,9 @@ break;

case XK_BackSpace: { unsigned int pos = findEmptySpaceLeft(); - m_text.erase(pos, m_cursor_pos - pos + m_start_pos); + FbString t = text(); + t.erase(pos, m_cursor_pos - pos + m_start_pos); + m_text.setLogical(t); if (pos < m_start_pos){ m_start_pos = pos;

@@ -278,10 +285,12 @@ adjustPos();

} break; case XK_Delete: { - if (!m_text.size() || m_cursor_pos >= m_text.size()) + if (text().empty() || m_cursor_pos >= text().size()) break; unsigned int pos = findEmptySpaceRight(); - m_text.erase(m_cursor_pos + m_start_pos, pos - (m_cursor_pos + m_start_pos)); + FbString t = text(); + t.erase(m_cursor_pos + m_start_pos, pos - (m_cursor_pos + m_start_pos)); + m_text.setLogical(t); adjustPos(); } break;

@@ -368,15 +377,17 @@ }

} void TextBox::adjustStartPos() { - - int text_width = font().textWidth(text(), m_end_pos); + + const char* visual = m_text.visual().c_str(); + + int text_width = font().textWidth(visual, m_end_pos); if (text_width < static_cast<signed>(width())) return; int start_pos = 0; while (text_width > static_cast<signed>(width())) { start_pos++; - text_width = font().textWidth(text().c_str() + start_pos, m_end_pos - start_pos); + text_width = font().textWidth(visual + start_pos, m_end_pos - start_pos); } // adjust cursorPosition() according relative to change to m_start_pos

@@ -387,12 +398,12 @@

unsigned int TextBox::findEmptySpaceLeft(){ // found the first left space symbol - int pos = m_text.rfind(' ', (m_start_pos + m_cursor_pos) > 0 ? + int pos = text().rfind(' ', (m_start_pos + m_cursor_pos) > 0 ? m_start_pos + m_cursor_pos - 1 : 0); // do we have one more space symbol near? int next_pos = -1; - while (pos > 0 && (next_pos = m_text.rfind(' ', pos - 1)) > -1){ + while (pos > 0 && (next_pos = text().rfind(' ', pos - 1)) > -1){ if (next_pos + 1 < pos) break; pos = next_pos;

@@ -406,18 +417,18 @@ }

unsigned int TextBox::findEmptySpaceRight(){ // found the first right space symbol - int pos = m_text.find(' ', m_start_pos + m_cursor_pos); + int pos = text().find(' ', m_start_pos + m_cursor_pos); // do we have one more space symbol near? int next_pos = -1; - while (pos > -1 && pos < static_cast<signed>(m_text.size()) && (next_pos = m_text.find(' ', pos + 1)) > -1 ){ + while (pos > -1 && pos < static_cast<signed>(text().size()) && (next_pos = text().find(' ', pos + 1)) > -1 ){ if (next_pos - 1 > pos) break; pos = next_pos; } if (pos < 0) - pos = m_text.size() - 1; + pos = text().size() - 1; return pos + 1; // (+1) - sets cursor at the right.
M src/FbTk/TextBox.hhsrc/FbTk/TextBox.hh

@@ -24,8 +24,7 @@ #define FBTK_TEXTBOX_HH

#include "FbWindow.hh" #include "EventHandler.hh" - -#include <string> +#include "FbString.hh" namespace FbTk {

@@ -37,7 +36,7 @@ TextBox(int screen_num, const Font &font, const std::string &text);

TextBox(const FbWindow &parent, const Font &font, const std::string &text); virtual ~TextBox(); - void setText(const std::string &text); + void setText(const FbTk::BiDiString &text); void setFont(const Font &font); void setGC(GC gc); void setCursorPosition(int cursor);

@@ -60,7 +59,7 @@ void exposeEvent(XExposeEvent &event);

void buttonPressEvent(XButtonEvent &event); void keyPressEvent(XKeyEvent &event); - const std::string &text() const { return m_text; } + const FbString &text() const { return m_text.logical(); } const Font &font() const { return *m_font; } GC gc() const { return m_gc; } int cursorPosition() const { return m_cursor_pos; }

@@ -76,7 +75,7 @@

void adjustPos(); const FbTk::Font *m_font; - std::string m_text; + BiDiString m_text; GC m_gc; std::string::size_type m_cursor_pos, m_start_pos, m_end_pos; };
M src/FbTk/TextButton.ccsrc/FbTk/TextButton.cc

@@ -28,7 +28,7 @@ namespace FbTk {

TextButton::TextButton(const FbTk::FbWindow &parent, FbTk::Font &font, - const std::string &text): + const FbTk::BiDiString &text): FbTk::Button(parent, 0, 0, 10, 10), m_font(&font), m_text(text),

@@ -81,8 +81,8 @@

return true; } -void TextButton::setText(const std::string &text) { - if (m_text != text) { +void TextButton::setText(const FbTk::BiDiString &text) { + if (m_text.logical() != text.logical()) { m_text = text; updateBackground(false); clear();

@@ -126,7 +126,7 @@ }

unsigned int TextButton::textWidth() const { - return font().textWidth(text(), text().size()); + return font().textWidth(text()); } void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) {

@@ -135,15 +135,15 @@ drawText(0, 0, &drawable);

} void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) { - unsigned int textlen = text().size(); - // do text alignment - - unsigned int textw = width(), texth = height(); + const FbString& visual = text().visual(); + unsigned int textlen = visual.size(); + unsigned int textw = width(); + unsigned int texth = height(); translateSize(m_orientation, textw, texth); int align_x = FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding, bevel(), justify(), font(), - text().data(), text().size(), + visual.data(), visual.size(), textlen); // return new text len // center text by default

@@ -161,25 +161,24 @@

font().drawText(*drawable, screenNumber(), gc(), // graphic context - text(), textlen, // string and string size + visual.c_str(), textlen, // string and string size textx, texty, m_orientation); // position } bool TextButton::textExceeds(int x_offset) { - - unsigned int textlen = text().size(); - // do text alignment - unsigned int textw = width(), texth = height(); + const FbString& visual = text().visual(); + unsigned int textlen = visual.size(); + unsigned int textw = width(); + unsigned int texth = height(); translateSize(m_orientation, textw, texth); FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding, - bevel(), justify(), font(), text().data(), text().size(), + bevel(), justify(), font(), visual.data(), visual.size(), textlen); // return new text len - return text().size()>textlen; - + return visual.size()>textlen; } void TextButton::exposeEvent(XExposeEvent &event) {
M src/FbTk/TextButton.hhsrc/FbTk/TextButton.hh

@@ -23,8 +23,7 @@ #ifndef FBTK_TEXTBUTTON_HH

#define FBTK_TEXTBUTTON_HH #include "Button.hh" - -#include <string> +#include "FbString.hh" namespace FbTk {

@@ -34,11 +33,11 @@ /// Displays a text on a button

class TextButton: public FbTk::Button, FbTk::FbWindowRenderer { public: TextButton(const FbTk::FbWindow &parent, - FbTk::Font &font, const std::string &text); + FbTk::Font &font, const FbTk::BiDiString &text); void setJustify(FbTk::Justify just); bool setOrientation(FbTk::Orientation orient); - void setText(const std::string &text); + void setText(const FbTk::BiDiString &text); void setFont(FbTk::Font &font); void setTextPadding(unsigned int padding); void setTextPaddingLeft(unsigned int leftpadding);

@@ -60,7 +59,7 @@

void renderForeground(FbDrawable &drawable); FbTk::Justify justify() const { return m_justify; } - const std::string &text() const { return m_text; } + const BiDiString &text() const { return m_text; } FbTk::Font &font() const { return *m_font; } FbTk::Orientation orientation() const { return m_orientation; } unsigned int textWidth() const;

@@ -75,7 +74,7 @@ bool textExceeds(int x_offset);

private: FbTk::Font *m_font; - std::string m_text; + BiDiString m_text; FbTk::Justify m_justify; FbTk::Orientation m_orientation;
M src/FbTk/XFontImp.ccsrc/FbTk/XFontImp.cc

@@ -97,8 +97,9 @@

return true; } -void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) { - if (m_fontstruct == 0) +void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient) { + + if (!text || !*text || m_fontstruct == 0) return; // use roated font functions?

@@ -107,21 +108,18 @@ drawRotText(w.drawable(), screen, gc, text, len, x, y, orient);

return; } - string localestr = text; - localestr.erase(len, string::npos); - localestr = FbStringUtil::FbStrToLocale(localestr); + std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, 0, len)); XSetFont(w.display(), gc, m_fontstruct->fid); XDrawString(w.display(), w.drawable(), gc, x, y, localestr.data(), localestr.size()); } -unsigned int XFontImp::textWidth(const FbString &text, unsigned int size) const { - if (text.empty() || m_fontstruct == 0) +unsigned int XFontImp::textWidth(const char* text, unsigned int size) const { + + if (!text || !*text || m_fontstruct == 0) return 0; - string localestr = text; - localestr.erase(size, string::npos); - localestr = FbStringUtil::FbStrToLocale(localestr); + std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, size)); return XTextWidth(m_fontstruct, localestr.data(), localestr.size()); }
M src/FbTk/XFontImp.hhsrc/FbTk/XFontImp.hh

@@ -32,11 +32,11 @@ public:

explicit XFontImp(const char *filename = 0); ~XFontImp(); bool load(const std::string &filename); - unsigned int textWidth(const FbString &text, unsigned int size) const; + unsigned int textWidth(const char* text, unsigned int len) const; unsigned int height() const; int ascent() const; int descent() const { return m_fontstruct ? m_fontstruct->descent : 0; } - void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient); + void drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient); bool validOrientation(FbTk::Orientation orient);
M src/FbTk/XftFontImp.ccsrc/FbTk/XftFontImp.cc

@@ -77,7 +77,10 @@

return true; } -void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) { +void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient) { + + if (!text || !*text) + return; if (!validOrientation(orient)) return;

@@ -98,12 +101,11 @@ y+=1;

break; } + Visual* def_visual = DefaultVisual(w.display(), screen); + Colormap def_colmap = DefaultColormap(w.display(), screen); + XftFont *font = m_xftfonts[orient]; - - XftDraw *draw = XftDrawCreate(w.display(), - w.drawable(), - DefaultVisual(w.display(), screen), - DefaultColormap(w.display(), screen)); + XftDraw *draw = XftDrawCreate(w.display(), w.drawable(), def_visual, def_colmap); XGCValues gc_val;

@@ -114,7 +116,7 @@

// get red, green, blue values XColor xcol; xcol.pixel = gc_val.foreground; - XQueryColor(w.display(), DefaultColormap(w.display(), screen), &xcol); + XQueryColor(w.display(), def_colmap, &xcol); // convert xcolor to XftColor XRenderColor rendcol;

@@ -123,10 +125,7 @@ rendcol.green = xcol.green;

rendcol.blue = xcol.blue; rendcol.alpha = 0xFFFF; XftColor xftcolor; - XftColorAllocValue(w.display(), - DefaultVisual(w.display(), screen), - DefaultColormap(w.display(), screen), - &rendcol, &xftcolor); + XftColorAllocValue(w.display(), def_visual, def_colmap, &rendcol, &xftcolor); // draw string #ifdef HAVE_XFT_UTF8_STRING

@@ -134,39 +133,25 @@ if (m_utf8mode) {

// check the string size, // if the size is zero we use the XftDrawString8 function instead. XGlyphInfo ginfo; - XftTextExtentsUtf8(w.display(), - m_xftfonts[ROT0], - (XftChar8 *)text.data(), len, - &ginfo); + XftTextExtentsUtf8(w.display(), m_xftfonts[ROT0], (XftChar8 *)text, len, &ginfo); if (ginfo.xOff != 0) { - XftDrawStringUtf8(draw, - &xftcolor, - font, - x, y, - (XftChar8 *)(text.data()), len); - XftColorFree(w.display(), - DefaultVisual(w.display(), screen), - DefaultColormap(w.display(), screen), &xftcolor); + XftDrawStringUtf8(draw, &xftcolor, font, x, y, (XftChar8 *)text, len); + XftColorFree(w.display(), def_visual, def_colmap, &xftcolor); XftDrawDestroy(draw); return; } } #endif // HAVE_XFT_UTF8_STRING - XftDrawString8(draw, - &xftcolor, - font, - x, y, - (XftChar8 *)(text.data()), len); + XftDrawString8(draw, &xftcolor, font, x, y, (XftChar8 *)text, len); - XftColorFree(w.display(), - DefaultVisual(w.display(), screen), - DefaultColormap(w.display(), screen), &xftcolor); + XftColorFree(w.display(), def_visual, def_colmap, &xftcolor); XftDrawDestroy(draw); } -unsigned int XftFontImp::textWidth(const FbString &text, unsigned int len) const { +unsigned int XftFontImp::textWidth(const char* text, unsigned int len) const { + if (m_xftfonts[ROT0] == 0) return 0;

@@ -180,7 +165,7 @@ #ifdef HAVE_XFT_UTF8_STRING

if (m_utf8mode) { XftTextExtentsUtf8(disp, font, - (XftChar8 *)text.data(), len, + (XftChar8 *)text, len, &ginfo); if (ginfo.xOff != 0) return ginfo.xOff;

@@ -189,9 +174,7 @@ // the utf8 failed, try normal extents

} #endif //HAVE_XFT_UTF8_STRING - std::string localestr = text; - localestr.erase(len, std::string::npos); - localestr = FbStringUtil::FbStrToLocale(localestr); + std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, len)); XftTextExtents8(disp, font,
M src/FbTk/XftFontImp.hhsrc/FbTk/XftFontImp.hh

@@ -34,8 +34,8 @@ public:

XftFontImp(const char *fontname, bool utf8); ~XftFontImp(); bool load(const std::string &name); - void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y , FbTk::Orientation orient); - unsigned int textWidth(const FbString &text, unsigned int len) const; + void drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y , FbTk::Orientation orient); + unsigned int textWidth(const char* text, unsigned int len) const; unsigned int height() const; int ascent() const { return m_xftfonts[0] ? m_xftfonts[0]->ascent : 0; } int descent() const { return m_xftfonts[0] ? m_xftfonts[0]->descent : 0; }
M src/FbTk/XmbFontImp.ccsrc/FbTk/XmbFontImp.cc

@@ -189,10 +189,10 @@

return true; } -void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const FbString &text, +void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient) { - if (m_fontset == 0) + if (!text || !*text || m_fontset == 0) return; if (orient == ROT0) {

@@ -200,13 +200,11 @@ #ifdef X_HAVE_UTF8_STRING

if (m_utf8mode) { Xutf8DrawString(d.display(), d.drawable(), m_fontset, main_gc, x, y, - text.data(), len); + text, len); } else #endif //X_HAVE_UTF8_STRING { - string localestr = text; - localestr.erase(len, string::npos); - localestr = FbStringUtil::FbStrToLocale(localestr); + std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, 0, len)); XmbDrawString(d.display(), d.drawable(), m_fontset, main_gc, x, y, localestr.data(), localestr.size());

@@ -239,13 +237,11 @@ #ifdef X_HAVE_UTF8_STRING

if (m_utf8mode) { Xutf8DrawString(dpy, canvas.drawable(), m_fontset, font_gc.gc(), xpos, ypos, - text.data(), len); + text, len); } else #endif //X_HAVE_UTF8_STRING { - string localestr = text; - localestr.erase(len, string::npos); - localestr = FbStringUtil::FbStrToLocale(localestr); + std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, 0, len)); XmbDrawString(dpy, canvas.drawable(), m_fontset, font_gc.gc(), xpos, ypos, localestr.data(), localestr.size());

@@ -277,25 +273,21 @@ XFreeGC(dpy, my_gc);

} -unsigned int XmbFontImp::textWidth(const FbString &text, unsigned int len) const { +unsigned int XmbFontImp::textWidth(const char* text, unsigned int len) const { + if (m_fontset == 0) return 0; XRectangle ink, logical; #ifdef X_HAVE_UTF8_STRING if (m_utf8mode) { - Xutf8TextExtents(m_fontset, text.data(), len, - &ink, &logical); + Xutf8TextExtents(m_fontset, text, len, &ink, &logical); if (logical.width != 0) return logical.width; } #endif // X_HAVE_UTF8_STRING - string localestr = text; - if (len > localestr.length()) - len = localestr.length(); - localestr.erase(len, string::npos); - localestr = FbStringUtil::FbStrToLocale(localestr); + std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, len)); XmbTextExtents(m_fontset, localestr.data(), localestr.size(), &ink, &logical); return logical.width;
M src/FbTk/XmbFontImp.hhsrc/FbTk/XmbFontImp.hh

@@ -32,8 +32,8 @@ public:

XmbFontImp(const char *fontname, bool utf8); ~XmbFontImp(); bool load(const std::string &name); - virtual void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient); - unsigned int textWidth(const FbString &text, unsigned int len) const; + virtual void drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient); + unsigned int textWidth(const char* text, unsigned int len) const; unsigned int height() const; int ascent() const { return m_setextents ? -m_setextents->max_ink_extent.y : 0; } int descent() const { return m_setextents ? m_setextents->max_ink_extent.height + m_setextents->max_ink_extent.y : 0; }
M src/FbWinFrame.ccsrc/FbWinFrame.cc

@@ -58,7 +58,7 @@ ButtonPressMask | ButtonReleaseMask |

ButtonMotionMask | ExposureMask | EnterWindowMask | LeaveWindowMask), m_tab_container(m_titlebar), - m_label(m_titlebar, m_theme->font(), ""), + m_label(m_titlebar, m_theme->font(), FbTk::BiDiString("")), m_handle(m_window, 0, 0, 100, 5, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | ExposureMask |
M src/FbWinFrame.hhsrc/FbWinFrame.hh

@@ -114,7 +114,7 @@

/// set focus/unfocus style void setFocus(bool newvalue); - void setFocusTitle(const std::string &str) { m_label.setText(str); } + void setFocusTitle(const FbTk::BiDiString &str) { m_label.setText(str); } bool setTabMode(TabMode tabmode); void updateTabProperties() { alignTabs(); }
M src/FocusControl.ccsrc/FocusControl.cc

@@ -564,7 +564,7 @@

fbdbg<<"------------------"<<endl; fbdbg<<"Setting Focused window = "<<client<<endl; if (client != 0) - fbdbg<<"title: "<<client->title()<<endl; + fbdbg<<"title: "<<client->title().logical()<<endl; fbdbg<<"Current Focused window = "<<s_focused_window<<endl; fbdbg<<"------------------"<<endl;
M src/Focusable.hhsrc/Focusable.hh

@@ -26,8 +26,7 @@ #include "FbTk/PixmapWithMask.hh"

#include "FbTk/ITypeAheadable.hh" #include "FbTk/Subject.hh" #include "FbTk/Signal.hh" - -#include <string> +#include "FbTk/FbString.hh" class BScreen; class FluxboxWindow;

@@ -83,9 +82,9 @@ */

FluxboxWindow *fbwindow() { return m_fbwin; } /// @return WM_CLASS class string (for pattern matching) - virtual const std::string &getWMClassClass() const { return m_class_name; } + virtual const FbTk::FbString &getWMClassClass() const { return m_class_name; } /// @return WM_CLASS name string (for pattern matching) - virtual const std::string &getWMClassName() const { return m_instance_name; } + virtual const FbTk::FbString &getWMClassName() const { return m_instance_name; } /// @return wm role string (for pattern matching) virtual std::string getWMRole() const { return "Focusable"; }

@@ -96,9 +95,9 @@ // so we can make nice buttons, menu entries, etc.

/// @return icon pixmap of the focusable virtual const FbTk::PixmapWithMask &icon() const { return m_icon; } /// @return title string - virtual const std::string &title() const { return m_title; } + virtual const FbTk::BiDiString &title() const { return m_title; } /// @return type ahead string - const std::string &iTypeString() const { return title(); } + const std::string &iTypeString() const { return title().logical(); } /** * Signaling object to attatch observers to. */

@@ -139,7 +138,10 @@ protected:

BScreen &m_screen; //< the screen in which it works FluxboxWindow *m_fbwin; //< the working fluxbox window - std::string m_title, m_instance_name, m_class_name; + FbTk::BiDiString m_title; + FbTk::FbString m_instance_name; + FbTk::FbString m_class_name; + bool m_focused; //< whether or not it has focus bool m_attention_state; //< state of icon button while demanding attention FbTk::PixmapWithMask m_icon; //< icon pixmap with mask
M src/Gnome.ccsrc/Gnome.cc

@@ -416,41 +416,40 @@

void Gnome::setLayer(FluxboxWindow *win, int layer) { if (!win) return; - + const FbTk::FbString& title = win->title().logical(); switch (layer) { case WIN_LAYER_DESKTOP: - fbdbg<<"Gnome::setLayer("<<win->title()<<", WIN_LAYER_DESKTOP)"<<endl; + fbdbg<<"Gnome::setLayer("<<title<<", WIN_LAYER_DESKTOP)"<<endl; layer = Layer::DESKTOP; break; case WIN_LAYER_BELOW: - fbdbg<<"Gnome::setLayer("<<win->title()<<", WIN_LAYER_BELOW)"<<endl; + fbdbg<<"Gnome::setLayer("<<title<<", WIN_LAYER_BELOW)"<<endl; layer = Layer::BOTTOM; break; case WIN_LAYER_NORMAL: - fbdbg<<"Gnome::setLayer("<<win->title()<<", WIN_LAYER_NORMAL)"<<endl; + fbdbg<<"Gnome::setLayer("<<title<<", WIN_LAYER_NORMAL)"<<endl; layer = Layer::NORMAL; break; case WIN_LAYER_ONTOP: - fbdbg<<"Gnome::setLayer("<<win->title()<<", WIN_LAYER_ONTOP)"<<endl; + fbdbg<<"Gnome::setLayer("<<title<<", WIN_LAYER_ONTOP)"<<endl; layer = Layer::TOP; break; case WIN_LAYER_DOCK: - fbdbg<<"Gnome::setLayer("<<win->title()<<", WIN_LAYER_DOCK)"<<endl; + fbdbg<<"Gnome::setLayer("<<title<<", WIN_LAYER_DOCK)"<<endl; layer = Layer::DOCK; break; case WIN_LAYER_ABOVE_DOCK: - fbdbg<<"Gnome::setLayer("<<win->title()<<", WIN_LAYER_ABOVE_DOCK)"<<endl; + fbdbg<<"Gnome::setLayer("<<title<<", WIN_LAYER_ABOVE_DOCK)"<<endl; layer = Layer::ABOVE_DOCK; break; case WIN_LAYER_MENU: - fbdbg<<"Gnome::setLayer("<<win->title()<<", WIN_LAYER_MENU)"<<endl; + fbdbg<<"Gnome::setLayer("<<title<<", WIN_LAYER_MENU)"<<endl; layer = Layer::MENU; break; default: // our windows are in the opposite direction to gnome layer = Layer::DESKTOP - layer; - - fbdbg<<"Gnome::setLayer("<<win->title()<<", "<<layer<<")"<<endl; + fbdbg<<"Gnome::setLayer("<<win->title().logical()<<", "<<layer<<")"<<endl; break; }
M src/IconbarTool.ccsrc/IconbarTool.cc

@@ -285,7 +285,7 @@ // must be internal menu, otherwise toolbar main menu tries to delete it.

m_menu.setInternalMenu(); // add iconbar menu to toolbar menu - menu.insert(m_menu.label(), &m_menu); + menu.insert(m_menu.label().logical(), &m_menu); // setup signals theme.reconfigSig().attach(this);

@@ -528,7 +528,7 @@ IconMap::iterator it = m_icons.find(&win);

if (it == m_icons.end()) return; - fbdbg<<"IconbarTool::"<<__FUNCTION__<<"( 0x"<<&win<<" title = "<<win.title()<<") found!"<<endl; + fbdbg<<"IconbarTool::"<<__FUNCTION__<<"( 0x"<<&win<<" title = "<<win.title().logical()<<") found!"<<endl; // remove from list and render theme again IconButton *button = it->second;

@@ -543,7 +543,7 @@ FluxboxWindow *fbwin = win.fbwindow();

if (!fbwin || fbwin->clientList().empty()) return 0; - fbdbg<<"IconbarTool::addWindow(0x"<<&win<<" title = "<<win.title()<<")"<<endl; + fbdbg<<"IconbarTool::addWindow(0x"<<&win<<" title = "<<win.title().logical()<<")"<<endl; IconButton *button = new IconButton(m_icon_container, m_focused_theme, m_unfocused_theme, win);

@@ -573,3 +573,4 @@ void IconbarTool::setOrientation(FbTk::Orientation orient) {

m_icon_container.setOrientation(orient); ToolbarItem::setOrientation(orient); } +
M src/OSDWindow.ccsrc/OSDWindow.cc

@@ -57,19 +57,19 @@ }

} -void OSDWindow::resize(const std::string &text) { +void OSDWindow::resize(const FbTk::BiDiString &text) { - int h = m_theme->font().height() + m_theme->bevelWidth()*2; - int w = m_theme->font().textWidth(text, text.size()) + - m_theme->bevelWidth()*2; + int bw = 2 * m_theme->bevelWidth(); + int h = m_theme->font().height() + bw; + int w = m_theme->font().textWidth(text) + bw; FbTk::FbWindow::resize(w, h); } -void OSDWindow::showText(const std::string &text) { +void OSDWindow::showText(const FbTk::BiDiString &text) { show(); clear(); m_theme->font().drawText(*this, m_screen.screenNumber(), - m_theme->iconbarTheme().text().textGC(), text, text.size(), + m_theme->iconbarTheme().text().textGC(), text, m_theme->bevelWidth(), m_theme->bevelWidth() + m_theme->font().ascent()); }
M src/OSDWindow.hhsrc/OSDWindow.hh

@@ -23,13 +23,13 @@ #ifndef OSDWINDOW_HH

#define OSDWINDOW_HH #include "FbTk/FbWindow.hh" -#include <string> class BScreen; class FbWinFrameTheme; namespace FbTk { template <class T> class ThemeProxy; +class BiDiString; } class OSDWindow: public FbTk::FbWindow {

@@ -41,8 +41,8 @@ m_screen(screen), m_theme(theme),

m_pixmap(None), m_visible(false) { } void reconfigTheme(); - void resize(const std::string &text); - void showText(const std::string &text); + void resize(const FbTk::BiDiString &text); + void showText(const FbTk::BiDiString &text); void hide(); bool isVisible() const { return m_visible; }
M src/Screen.ccsrc/Screen.cc

@@ -1051,7 +1051,7 @@ m_workspaces_list.size());

m_workspaces_list.push_back(wkspc); if (save_name) { - addWorkspaceName(wkspc->name().c_str()); //update names + addWorkspaceName(wkspc->name().c_str()); m_workspacenames_sig.emit(*this); }

@@ -1451,7 +1451,7 @@

void BScreen::rereadMenu() { m_rootmenu->removeAll(); - m_rootmenu->setLabel(""); + m_rootmenu->setLabel(FbTk::BiDiString("")); Fluxbox * const fb = Fluxbox::instance(); if (!fb->getMenuFilename().empty())

@@ -1776,8 +1776,10 @@ void BScreen::showPosition(int x, int y) {

if (!doShowWindowPos()) return; - char label[256]; - sprintf(label, "X:%5d x Y:%5d", x, y); + char buf[256]; + sprintf(buf, "X:%5d x Y:%5d", x, y); + + FbTk::BiDiString label(buf); m_pos_window->showText(label); }

@@ -1790,19 +1792,21 @@ void BScreen::showGeometry(unsigned int gx, unsigned int gy) {

if (!doShowWindowPos()) return; - char label[256]; + char buf[256]; _FB_USES_NLS; - sprintf(label, + sprintf(buf, _FB_XTEXT(Screen, GeometryFormat, "W: %4d x H: %4d", "Format for width and height window, %4d for width, and %4d for height").c_str(), gx, gy); + + FbTk::BiDiString label(buf); m_geom_window->showText(label); } -void BScreen::showTooltip(const std::string &text) { +void BScreen::showTooltip(const FbTk::BiDiString &text) { if (*resource.tooltip_delay >= 0) m_tooltip_window->showText(text); }

@@ -1855,20 +1859,22 @@

void BScreen::renderGeomWindow() { - char label[256]; + char buf[256]; _FB_USES_NLS; - sprintf(label, + sprintf(buf, _FB_XTEXT(Screen, GeometrySpacing, "W: %04d x H: %04d", "Representative maximum sized text for width and height dialog").c_str(), 0, 0); + + FbTk::BiDiString label(buf); m_geom_window->resize(label); m_geom_window->reconfigTheme(); } void BScreen::renderPosWindow() { - m_pos_window->resize("0:00000 x 0:00000"); + m_pos_window->resize(FbTk::BiDiString("0:00000 x 0:00000")); m_pos_window->reconfigTheme(); }
M src/Screen.hhsrc/Screen.hh

@@ -380,7 +380,7 @@ void showGeometry(unsigned int width, unsigned int height);

void hideGeometry(); /// @param text the text to be displayed in the tooltip window - void showTooltip(const std::string &text); + void showTooltip(const FbTk::BiDiString &text); /// Hides the tooltip window void hideTooltip();
M src/Slit.ccsrc/Slit.cc

@@ -169,13 +169,13 @@

class SlitClientMenuItem: public FbTk::MenuItem{ public: explicit SlitClientMenuItem(Slit& slit, SlitClient &client, FbTk::RefCount<FbTk::Command<void> > &cmd): - FbTk::MenuItem(client.matchName().c_str(), cmd), m_slit(slit), m_client(client) { + FbTk::MenuItem(client.matchName(), cmd), m_slit(slit), m_client(client) { setCommand(cmd); FbTk::MenuItem::setSelected(client.visible()); setToggleItem(true); setCloseOnClick(false); } - const string &label() const { + const FbTk::BiDiString &label() const { return m_client.matchName(); } bool isSelected() const {

@@ -345,44 +345,44 @@ screen().updateAvailableWorkspaceArea();

return; } - unsigned int bw = m_slit_theme->borderWidth(); + const unsigned int bw = m_slit_theme->borderWidth() * 2; int left = 0, right = 0, top = 0, bottom = 0; switch (placement()) { case TOPLEFT: - top = height() + 2 * bw; + top = height() + bw; break; case LEFTTOP: - left = width() + 2 * bw; + left = width() + bw; break; case TOPCENTER: - top = height() + 2 * bw; + top = height() + bw; break; case TOPRIGHT: - top = height() + 2 * bw; + top = height() + bw; break; case RIGHTTOP: - right = width() + 2 * bw; + right = width() + bw; break; case BOTTOMLEFT: - bottom = height() + 2 * bw; + bottom = height() + bw; break; case LEFTBOTTOM: - left = width() + 2 * bw; + left = width() + bw; break; case BOTTOMCENTER: - bottom = height() + 2 * bw; + bottom = height() + bw; break; case BOTTOMRIGHT: - bottom = height() + 2 * bw; + bottom = height() + bw; break; case RIGHTBOTTOM: - right = width() + 2 * bw; + right = width() + bw; break; case LEFTCENTER: - left = width() + 2 * bw; + left = width() + bw; break; case RIGHTCENTER: - right = width() + 2 * bw; + right = width() + bw; break; }

@@ -403,14 +403,13 @@ return;

// Look for slot in client list by name SlitClient *client = 0; - string match_name; - match_name = Xutil::getWMClassName(w); + FbTk::FbString match_name = Xutil::getWMClassName(w); SlitClients::iterator it = m_client_list.begin(); SlitClients::iterator it_end = m_client_list.end(); bool found_match = false; for (; it != it_end; ++it) { // If the name matches... - if ((*it)->matchName() == match_name) { + if ((*it)->matchName().logical() == match_name) { // Use the slot if no window is assigned if ((*it)->window() == None) { client = (*it);

@@ -1158,7 +1157,7 @@ SlitClients::iterator it_end = m_client_list.end();

string prevName; string name; for (; it != it_end; ++it) { - name = (*it)->matchName(); + name = (*it)->matchName().logical(); if (name != prevName) file << name.c_str() << endl;
M src/SlitClient.ccsrc/SlitClient.cc

@@ -22,8 +22,9 @@

#include "SlitClient.hh" #include "Screen.hh" +#include "Xutil.hh" + #include "FbTk/App.hh" -#include "Xutil.hh" #include <X11/Xutil.h> #include <X11/Xatom.h>

@@ -32,7 +33,8 @@ SlitClient::SlitClient(BScreen *screen, Window win) {

initialize(screen, win); } -SlitClient::SlitClient(const char *name):m_match_name(name == 0 ? "" : name) { +SlitClient::SlitClient(const char *name) : + m_match_name(FbTk::BiDiString(!name ? "" : name)) { initialize(); }

@@ -50,9 +52,9 @@ m_window = m_icon_window = None;

move(0, 0); resize(0, 0); - if (matchName().empty()) - m_match_name = Xutil::getWMClassName(clientWindow()); - m_visible = true; + if (matchName().logical().empty()) + m_match_name.setLogical(Xutil::getWMClassName(clientWindow())); + m_visible = true; } void SlitClient::disableEvents() {
M src/SlitClient.hhsrc/SlitClient.hh

@@ -22,10 +22,10 @@

#ifndef SLITCLIENT_HH #define SLITCLIENT_HH +#include "FbTk/FbString.hh" #include "FbTk/NotCopyable.hh" #include <X11/Xlib.h> -#include <string> class BScreen;

@@ -37,7 +37,7 @@ SlitClient(BScreen *screen, Window win);

/// For adding a placeholder explicit SlitClient(const char *name); - const std::string &matchName() const { return m_match_name; } + const FbTk::BiDiString &matchName() const { return m_match_name; } Window window() const { return m_window; } Window clientWindow() const { return m_client_window; } Window iconWindow() const { return m_icon_window; }

@@ -62,7 +62,7 @@ void disableEvents();

void enableEvents(); private: - std::string m_match_name; + FbTk::BiDiString m_match_name; Window m_window, m_client_window, m_icon_window; int m_x, m_y; unsigned int m_width, m_height;
M src/TextDialog.ccsrc/TextDialog.cc

@@ -62,7 +62,7 @@ m_screen.imageControl().removeImage(m_pixmap);

} -void TextDialog::setText(const string &text) { +void TextDialog::setText(const FbTk::BiDiString& text) { m_textbox.setText(text); }
M src/TextDialog.hhsrc/TextDialog.hh

@@ -32,9 +32,9 @@ class TextDialog: public FbTk::FbWindow, public FbTk::EventHandler {

public: TextDialog(BScreen &screen, const std::string &title); virtual ~TextDialog(); - + /// Sets the entry text. - void setText(const std::string &text); + void setText(const FbTk::BiDiString& text); void show(); void hide();
M src/TooltipWindow.ccsrc/TooltipWindow.cc

@@ -38,7 +38,7 @@ m_timer.fireOnce(true);

} -void TooltipWindow::showText(const std::string &text) { +void TooltipWindow::showText(const FbTk::BiDiString& text) { m_lastText = text; if (m_delay == 0)

@@ -50,13 +50,13 @@ }

void TooltipWindow::raiseTooltip() { - if (m_lastText.empty()) + if (m_lastText.logical().empty()) return; resize(m_lastText); reconfigTheme(); int h = theme()->font().height() + theme()->bevelWidth() * 2; - int w = theme()->font().textWidth(m_lastText, m_lastText.size()) + theme()->bevelWidth() * 2; + int w = theme()->font().textWidth(m_lastText) + theme()->bevelWidth() * 2; Window root_ret; // not used Window window_ret; // not used

@@ -92,12 +92,12 @@ show();

clear(); theme()->font().drawText(*this, screen().screenNumber(), theme()->iconbarTheme().text().textGC(), - m_lastText, m_lastText.size(), + m_lastText, theme()->bevelWidth(), theme()->bevelWidth() + theme()->font().ascent()); } -void TooltipWindow::updateText(const std::string &text) { +void TooltipWindow::updateText(const FbTk::BiDiString& text) { m_lastText = text; raiseTooltip(); }
M src/TooltipWindow.hhsrc/TooltipWindow.hh

@@ -27,6 +27,7 @@ #include "FbTk/Command.hh"

#include "FbTk/RefCount.hh" #include "FbTk/Timer.hh" #include "FbTk/SimpleCommand.hh" +#include "FbTk/FbString.hh" /** * Displays a tooltip window

@@ -39,9 +40,9 @@ /**

* Sets the text in the window and starts the display timer. * @param text the text to show in the window. */ - void showText(const std::string &text); + void showText(const FbTk::BiDiString& text); /// updates the text directly without any delay - void updateText(const std::string &text); + void updateText(const FbTk::BiDiString& text); /// Sets the delay before the window pops up void setDelay(int delay) {

@@ -56,10 +57,9 @@ private:

void raiseTooltip(); void show(); int m_delay; ///< delay time for the timer - std::string m_lastText; ///< last text to be displayed + FbTk::BiDiString m_lastText; ///< last text to be displayed FbTk::Timer m_timer; ///< delay timer before the tooltip will show }; +#endif // TOOLTIPWINDOW_HH_ - -#endif // TOOLTIPWINDOW_HH_
M src/WinClient.ccsrc/WinClient.cc

@@ -340,14 +340,14 @@ // the limitation to 512 chars only avoids running in that trap

if (m_title_override) return; - m_title = string(Xutil::getWMName(window()), 0, 512); - titleSig().emit(m_title, *this); + m_title.setLogical(FbTk::FbString(Xutil::getWMName(window()), 0, 512)); + titleSig().emit(m_title.logical(), *this); } void WinClient::setTitle(const FbTk::FbString &title) { - m_title = title; + m_title.setLogical(title); m_title_override = true; - titleSig().emit(m_title, *this); + titleSig().emit(m_title.logical(), *this); } void WinClient::setIcon(const FbTk::PixmapWithMask& pm) {

@@ -355,7 +355,7 @@

m_icon.pixmap().copy(pm.pixmap()); m_icon.mask().copy(pm.mask()); m_icon_override = true; - titleSig().emit(m_title, *this); + titleSig().emit(m_title.logical(), *this); } void WinClient::setFluxboxWindow(FluxboxWindow *win) {
M src/Window.ccsrc/Window.cc

@@ -329,7 +329,7 @@ unregisterWindow(frame().window().window());

} - const char* title = m_client ? m_client->title().c_str() : "" ; + const char* title = m_client ? m_client->title().logical().c_str() : "" ; fbdbg<<"starting ~FluxboxWindow("<<this<<","<<title<<")"<<endl; fbdbg<<"num clients = "<<numClients()<<endl; fbdbg<<"curr client = "<<m_client<<endl;

@@ -487,11 +487,11 @@ m_client->transientFor()->fbwindow()->workspaceNumber();

} else // if no parent then set default layer moveToLayer(m_state.layernum, m_state.layernum != ::Layer::NORMAL); - fbdbg<<"FluxboxWindow::init("<<title()<<") transientFor: "<< + fbdbg<<"FluxboxWindow::init("<<title().logical()<<") transientFor: "<< m_client->transientFor()<<endl; if (m_client->transientFor() && m_client->transientFor()->fbwindow()) { - fbdbg<<"FluxboxWindow::init("<<title()<<") transientFor->title(): "<< - m_client->transientFor()->fbwindow()->title()<<endl; + fbdbg<<"FluxboxWindow::init("<<title().logical()<<") transientFor->title(): "<< + m_client->transientFor()->fbwindow()->title().logical()<<endl; }

@@ -976,7 +976,7 @@ fbdbg<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<<

button<<endl; if (old != &client) { - titleSig().emit(title(), *this); + titleSig().emit(title().logical(), *this); frame().setFocusTitle(title()); frame().setShapingClient(&client, false); }

@@ -1627,7 +1627,7 @@ void FluxboxWindow::raise() {

if (isIconic()) return; - fbdbg<<"FluxboxWindow("<<title()<<")::raise()[layer="<<layerNum()<<"]"<<endl; + fbdbg<<"FluxboxWindow("<<title().logical()<<")::raise()[layer="<<layerNum()<<"]"<<endl; // get root window WinClient *client = getRootTransientFor(m_client);

@@ -1655,7 +1655,7 @@ void FluxboxWindow::lower() {

if (isIconic()) return; - fbdbg<<"FluxboxWindow("<<title()<<")::lower()"<<endl; + fbdbg<<"FluxboxWindow("<<title().logical()<<")::lower()"<<endl; /* Ignore all EnterNotify events until the pointer actually moves */ screen().focusControl().ignoreAtPointer();

@@ -1686,7 +1686,7 @@ }

void FluxboxWindow::moveToLayer(int layernum, bool force) { - fbdbg<<"FluxboxWindow("<<title()<<")::moveToLayer("<<layernum<<")"<<endl; + fbdbg<<"FluxboxWindow("<<title().logical()<<")::moveToLayer("<<layernum<<")"<<endl; // don't let it set its layer into menu area if (layernum <= ::Layer::MENU)

@@ -1751,7 +1751,7 @@

bool was_focused = isFocused(); m_focused = focus; - fbdbg<<"FluxboxWindow("<<title()<<")::setFocusFlag("<<focus<<")"<<endl; + fbdbg<<"FluxboxWindow("<<title().logical()<<")::setFocusFlag("<<focus<<")"<<endl; installColormap(focus);

@@ -1942,7 +1942,7 @@ */

void FluxboxWindow::handleEvent(XEvent &event) { switch (event.type) { case ConfigureRequest: - fbdbg<<"ConfigureRequest("<<title()<<")"<<endl; + fbdbg<<"ConfigureRequest("<<title().logical()<<")"<<endl; configureRequestEvent(event.xconfigurerequest); break;

@@ -1957,7 +1957,7 @@ case PropertyNotify: {

#ifdef DEBUG char *atomname = XGetAtomName(display, event.xproperty.atom); - fbdbg<<"PropertyNotify("<<title()<<"), property = "<<atomname<<endl; + fbdbg<<"PropertyNotify("<<title().logical()<<"), property = "<<atomname<<endl; if (atomname) XFree(atomname); #endif // DEBUG

@@ -1973,7 +1973,7 @@ #ifdef SHAPE

if (Fluxbox::instance()->haveShape() && event.type == Fluxbox::instance()->shapeEventbase() + ShapeNotify) { - fbdbg<<"ShapeNotify("<<title()<<")"<<endl; + fbdbg<<"ShapeNotify("<<title().logical()<<")"<<endl; XShapeEvent *shape_event = (XShapeEvent *)&event;

@@ -2068,7 +2068,7 @@ return;

fbdbg<<"("<<__FUNCTION__<<"): 0x"<<hex<<client->window()<<dec<<endl; - fbdbg<<"("<<__FUNCTION__<<"): title="<<client->title()<<endl; + fbdbg<<"("<<__FUNCTION__<<"): title="<<client->title().logical()<<endl; restore(client, false);

@@ -2081,7 +2081,7 @@ we just hide it for now.

*/ void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) { if (de.window == m_client->window()) { - fbdbg<<"DestroyNotifyEvent this="<<this<<" title = "<<title()<<endl; + fbdbg<<"DestroyNotifyEvent this="<<this<<" title = "<<title().logical()<<endl; delete m_client; if (numClients() == 0) delete this;

@@ -2109,7 +2109,7 @@ } break;

case XA_WM_HINTS: client.updateWMHints(); - titleSig().emit(title(), *this); + titleSig().emit(title().logical(), *this); // nothing uses this yet // hintSig().notify(); // notify listeners break;

@@ -2123,7 +2123,7 @@ client.updateTitle();

break; case XA_WM_NORMAL_HINTS: { - fbdbg<<"XA_WM_NORMAL_HINTS("<<title()<<")"<<endl; + fbdbg<<"XA_WM_NORMAL_HINTS("<<title().logical()<<")"<<endl; unsigned int old_max_width = client.maxWidth(); unsigned int old_min_width = client.minWidth(); unsigned int old_min_height = client.minHeight();

@@ -3347,19 +3347,19 @@ return m_client->window();

} -const string &FluxboxWindow::title() const { +const FbTk::BiDiString& FluxboxWindow::title() const { return (m_client ? m_client->title() : m_title); } -const std::string &FluxboxWindow::getWMClassName() const { +const FbTk::FbString& FluxboxWindow::getWMClassName() const { return (m_client ? m_client->getWMClassName() : getWMClassName()); } -const std::string &FluxboxWindow::getWMClassClass() const { +const FbTk::FbString& FluxboxWindow::getWMClassClass() const { return (m_client ? m_client->getWMClassClass() : getWMClassClass()); } -std::string FluxboxWindow::getWMRole() const { +FbTk::FbString FluxboxWindow::getWMRole() const { return (m_client ? m_client->getWMRole() : "FluxboxWindow"); }
M src/Window.hhsrc/Window.hh

@@ -418,9 +418,9 @@ FbTk::FbWindow &parent() { return m_parent; }

bool acceptsFocus() const; const FbTk::PixmapWithMask &icon() const; - const std::string &title() const; - const std::string &getWMClassName() const; - const std::string &getWMClassClass() const; + const FbTk::BiDiString &title() const; + const FbTk::FbString &getWMClassName() const; + const FbTk::FbString &getWMClassClass() const; std::string getWMRole() const; void setWindowType(WindowState::WindowType type); bool isTransient() const;
M src/Workspace.ccsrc/Workspace.cc

@@ -171,7 +171,7 @@ }

screen().updateWorkspaceName(m_id); - menu().setLabel(m_name); + menu().setLabel(FbTk::BiDiString(m_name)); menu().updateMenu(); }
M src/Workspace.hhsrc/Workspace.hh

@@ -48,7 +48,7 @@ unsigned int workspaceid = 0);

~Workspace(); /// Set workspace name - void setName(const std::string &name); + void setName(const FbTk::FbString& name); /// Deiconify all windows on this workspace void showAll(); void hideAll(bool interrupt_moving);

@@ -68,7 +68,7 @@

FbTk::Menu &menu() { return m_clientmenu; } const FbTk::Menu &menu() const { return m_clientmenu; } /// name of this workspace - const std::string &name() const { return m_name; } + const FbTk::FbString &name() const { return m_name; } /** @return the number of this workspace, note: obsolete, should be in BScreen */

@@ -88,7 +88,7 @@ Windows m_windowlist;

FbTk::Signal<void> m_clientlist_sig; ClientMenu m_clientmenu; - std::string m_name; ///< name of this workspace + FbTk::FbString m_name; ///< name of this workspace unsigned int m_id; ///< id, obsolete, this should be in BScreen };
M src/WorkspaceMenu.ccsrc/WorkspaceMenu.cc

@@ -72,9 +72,7 @@ for (size_t workspace = 0; workspace < screen.numberOfWorkspaces();

++workspace) { Workspace *wkspc = screen.getWorkspace(workspace); wkspc->menu().setInternalMenu(); - FbTk::MultiButtonMenuItem* mb_menu = new FbTk::MultiButtonMenuItem(5, - wkspc->name().c_str(), - &wkspc->menu()); + FbTk::MultiButtonMenuItem* mb_menu = new FbTk::MultiButtonMenuItem(5, FbTk::BiDiString(wkspc->name()), &wkspc->menu()); FbTk::RefCount<FbTk::Command<void> > jump_cmd(new JumpToWorkspaceCmd(wkspc->workspaceID())); mb_menu->setCommand(3, jump_cmd); insert(mb_menu, workspace + IDX_AFTER_ICONS);

@@ -119,9 +117,7 @@ // for each workspace add workspace name and it's menu to our workspace menu

for (size_t workspace = 0; workspace < screen.numberOfWorkspaces(); ++workspace) { Workspace *wkspc = screen.getWorkspace(workspace); wkspc->menu().setInternalMenu(); - FbTk::MultiButtonMenuItem* mb_menu = new FbTk::MultiButtonMenuItem(5, - wkspc->name().c_str(), - &wkspc->menu()); + FbTk::MultiButtonMenuItem* mb_menu = new FbTk::MultiButtonMenuItem(5, FbTk::BiDiString(wkspc->name()), &wkspc->menu()); FbTk::RefCount<FbTk::Command<void> > jump_cmd(new JumpToWorkspaceCmd(wkspc->workspaceID())); mb_menu->setCommand(3, jump_cmd); insert(mb_menu, workspace + IDX_AFTER_ICONS);
M src/WorkspaceNameTool.ccsrc/WorkspaceNameTool.cc

@@ -34,7 +34,7 @@

WorkspaceNameTool::WorkspaceNameTool(const FbTk::FbWindow &parent, FbTk::ThemeProxy<ToolTheme> &theme, BScreen &screen): ToolbarItem(ToolbarItem::FIXED), - m_button(parent, theme->font(), "a workspace name"), + m_button(parent, theme->font(), FbTk::BiDiString("a workspace name")), m_theme(theme), m_screen(screen), m_pixmap(0) {

@@ -93,9 +93,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, name.size()), - max_size); + max_size = std::max(m_theme->font().textWidth((*it)->name()), max_size); } // so align text dont cut the last character max_size += 2;

@@ -111,9 +109,7 @@ unsigned int max_size = 0;

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, name.size()), - max_size); + max_size = std::max(m_theme->font().textWidth((*it)->name()), max_size); } // so align text dont cut the last character max_size += 2;
M src/Xutil.ccsrc/Xutil.cc

@@ -46,7 +46,7 @@

FbTk::FbString getWMName(Window window) { if (window == None) - return ""; + return FbTk::FbString(""); Display *display = FbTk::App::instance()->display();

@@ -55,7 +55,7 @@ text_prop.value = 0;

char **list = 0; int num = 0; _FB_USES_NLS; - string name; + FbTk::FbString name; if (XGetWMName(display, window, &text_prop)) { if (text_prop.value && text_prop.nitems > 0) {

@@ -90,9 +90,10 @@ }

// The name of this particular instance -string getWMClassName(Window win) { +FbTk::FbString getWMClassName(Window win) { + XClassHint ch; - string instance_name; + FbTk::FbString instance_name; if (XGetClassHint(FbTk::App::instance()->display(), win, &ch) == 0) { fbdbg<<"Xutil: Failed to read class hint!"<<endl;

@@ -111,13 +112,13 @@ instance_name = "";

} return instance_name; - } // the name of the general class of the app -string getWMClassClass(Window win) { +FbTk::FbString getWMClassClass(Window win) { + XClassHint ch; - string class_name; + FbTk::FbString class_name; if (XGetClassHint(FbTk::App::instance()->display(), win, &ch) == 0) { fbdbg<<"Xutil: Failed to read class hint!"<<endl;
M src/Xutil.hhsrc/Xutil.hh

@@ -30,8 +30,8 @@ namespace Xutil {

FbTk::FbString getWMName(Window window); -std::string getWMClassName(Window win); -std::string getWMClassClass(Window win); +FbTk::FbString getWMClassName(Window win); +FbTk::FbString getWMClassClass(Window win); } // end namespace Xutil
M util/fbrun/FbRun.ccutil/fbrun/FbRun.cc

@@ -334,11 +334,13 @@ if (m_current_history_item == m_history.size()) {

XBell(m_display, 0); } else { m_current_history_item++; + FbTk::BiDiString text(""); if (m_current_history_item == m_history.size()) { m_current_history_item = m_history.size(); - setText(""); - } else - setText(m_history[m_current_history_item]); + } else + text.setLogical((m_history[m_current_history_item])); + + setText(text); } }

@@ -347,7 +349,7 @@ if (m_history.size() == 0 || m_current_history_item == 0) {

XBell(m_display, 0); } else { m_current_history_item = 0; - setText(m_history[m_current_history_item]); + setText(FbTk::BiDiString(m_history[m_current_history_item])); } }

@@ -357,7 +359,7 @@ if (m_history.size() == 0) {

XBell(m_display, 0); } else { m_current_history_item = m_history.size(); - setText(""); + setText(FbTk::BiDiString("")); } }

@@ -373,7 +375,7 @@

while (history_item != m_current_history_item && nr++ < m_history.size()) { if (m_history[history_item].find(m_last_completion_prefix) == 0) { m_current_history_item = history_item; - setText(m_history[m_current_history_item]); + setText(FbTk::BiDiString(m_history[m_current_history_item])); cursorEnd(); break; }