diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-07 21:32:57 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-07 21:32:57 +0000 |
commit | 3317e2755360c9c36258d45d48c502ffe79e45ba (patch) | |
tree | 53cfb96c842be890f457d77d221586ab546c9489 | |
parent | 965e4c45ae4111d7a36a3606bb984db2fc5ff39e (diff) | |
download | chromium_src-3317e2755360c9c36258d45d48c502ffe79e45ba.zip chromium_src-3317e2755360c9c36258d45d48c502ffe79e45ba.tar.gz chromium_src-3317e2755360c9c36258d45d48c502ffe79e45ba.tar.bz2 |
[GTK] change workaround for weird RTL label alignment
When a GtkLabel has line wrapping and an integer size request, the text block is left aligned even in RTL locales. It will wrap at the left (which is correct) and be right justified (also correct) but is flush with the left of the widget allocation instead of the right of the widget allocation.
seems not to occur when the size is controled via gtk_label_set_width_chars() instead of gtk_widget_set_size_request(). (also goes away when line wrapping is turned off)
TODO: file a reduction upstream.
BUG=52857
TEST=launch chrome in Hebrew and look at the under the hood tab of options. Checkbox labels should look correct
Review URL: http://codereview.chromium.org/3355007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58758 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | app/gtk_util.cc | 20 | ||||
-rw-r--r-- | app/gtk_util.h | 4 | ||||
-rw-r--r-- | chrome/browser/gtk/extension_install_prompt2_gtk.cc | 22 | ||||
-rw-r--r-- | chrome/browser/gtk/options/advanced_contents_gtk.cc | 10 | ||||
-rw-r--r-- | chrome/browser/gtk/options/languages_page_gtk.cc | 10 |
5 files changed, 53 insertions, 13 deletions
diff --git a/app/gtk_util.cc b/app/gtk_util.cc index 98e5d48..5eade5b 100644 --- a/app/gtk_util.cc +++ b/app/gtk_util.cc @@ -74,6 +74,26 @@ void GetWidgetSizeFromCharacters( g_object_unref(context); } +int GetCharacterWidthForPixels(GtkWidget* widget, int pixel_width) { + DCHECK(GTK_WIDGET_REALIZED(widget)) + << " widget must be realized to compute font metrics correctly"; + + PangoContext* context = gtk_widget_create_pango_context(widget); + PangoFontMetrics* metrics = pango_context_get_metrics(context, + widget->style->font_desc, pango_context_get_language(context)); + + // This technique (max of char and digit widths) matches the code in + // gtklabel.c. + int char_width = pixel_width * PANGO_SCALE / + std::max(pango_font_metrics_get_approximate_char_width(metrics), + pango_font_metrics_get_approximate_digit_width(metrics)); + + pango_font_metrics_unref(metrics); + g_object_unref(context); + + return char_width; +} + void ApplyMessageDialogQuirks(GtkWidget* dialog) { if (gtk_window_get_modal(GTK_WINDOW(dialog))) { // Work around a KDE 3 window manager bug. diff --git a/app/gtk_util.h b/app/gtk_util.h index 6225d3e..cbb91e9 100644 --- a/app/gtk_util.h +++ b/app/gtk_util.h @@ -27,6 +27,10 @@ void GetWidgetSizeFromCharacters( GtkWidget* widget, double width_chars, double height_lines, int* width, int* height); +// Returns the approximate number of characters that can horizontally +// fit in |pixel_width| pixels. +int GetCharacterWidthForPixels(GtkWidget* widget, int pixel_width); + // A helper function for gtk_message_dialog_new() to work around a KDE 3 // window manager bugs. You should always call it after creating a dialog // with gtk_message_dialog_new. diff --git a/chrome/browser/gtk/extension_install_prompt2_gtk.cc b/chrome/browser/gtk/extension_install_prompt2_gtk.cc index 1ab571a..4a88c73 100644 --- a/chrome/browser/gtk/extension_install_prompt2_gtk.cc +++ b/chrome/browser/gtk/extension_install_prompt2_gtk.cc @@ -4,6 +4,7 @@ #include <gtk/gtk.h> +#include "app/gtk_util.h" #include "app/l10n_util.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" @@ -28,6 +29,13 @@ const int kImageSize = 69; // Padding on all sides of each permission in the permissions list. const int kPermissionsPadding = 8; +void LabelRealized(GtkWidget* label, gpointer unused) { + gtk_label_set_width_chars( + GTK_LABEL(label), + gtk_util::GetCharacterWidthForPixels(label, + kRightColumnMinWidth)); +} + // Make a GtkLabel with |str| as its text, using the formatting in |format|. GtkWidget* MakeMarkupLabel(const char* format, const std::string& str) { GtkWidget* label = gtk_label_new(NULL); @@ -114,18 +122,10 @@ void ShowInstallPromptDialog2(GtkWindow* parent, SkBitmap* skia_icon, label).c_str()); gtk_label_set_line_wrap(GTK_LABEL(warning_label), TRUE); gtk_misc_set_alignment(GTK_MISC(warning_label), 0.0, 0.5); + g_signal_connect(warning_label, "realize", G_CALLBACK(LabelRealized), NULL); - // We set the size request for the right column width here so that it will - // be overridden by the title if the title is long. We use the bin because - // if we set a size request on the label itself, GTK+ uses that when - // justifying the label. Older versions of GTK+ use the label's allocation, - // but newer versions use the size request. This can lead to alignment - // problems in RTL locales. See http://crbug.com/52857 - GtkWidget* bin = gtk_event_box_new(); - gtk_container_add(GTK_CONTAINER(bin), warning_label); - gtk_widget_set_size_request(bin, kRightColumnMinWidth, -1); - - gtk_box_pack_start(GTK_BOX(right_column_area), bin, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(right_column_area), warning_label, + FALSE, FALSE, 0); GtkWidget* frame = gtk_frame_new(NULL); gtk_box_pack_start(GTK_BOX(right_column_area), frame, FALSE, FALSE, 0); diff --git a/chrome/browser/gtk/options/advanced_contents_gtk.cc b/chrome/browser/gtk/options/advanced_contents_gtk.cc index 50c5752..d31576e 100644 --- a/chrome/browser/gtk/options/advanced_contents_gtk.cc +++ b/chrome/browser/gtk/options/advanced_contents_gtk.cc @@ -76,11 +76,19 @@ const int kWrapWidth = 445; const int kWrapWidth = 475; #endif +// We can't calculate the proper width until the label is realized. +void LabelRealized(GtkWidget* label, gpointer unused) { + gtk_label_set_width_chars( + GTK_LABEL(label), + gtk_util::GetCharacterWidthForPixels(label, kWrapWidth)); +} + GtkWidget* CreateWrappedLabel(int string_id) { GtkWidget* label = gtk_label_new( l10n_util::GetStringUTF8(string_id).c_str()); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_widget_set_size_request(label, kWrapWidth, -1); + g_signal_connect(label, "realize", G_CALLBACK(LabelRealized), NULL); return label; } diff --git a/chrome/browser/gtk/options/languages_page_gtk.cc b/chrome/browser/gtk/options/languages_page_gtk.cc index 2ad3496..7a4e092 100644 --- a/chrome/browser/gtk/options/languages_page_gtk.cc +++ b/chrome/browser/gtk/options/languages_page_gtk.cc @@ -9,6 +9,7 @@ #include <vector> #include "app/gtk_signal.h" +#include "app/gtk_util.h" #include "app/l10n_util.h" #include "base/command_line.h" #include "base/message_loop.h" @@ -36,6 +37,12 @@ GtkWidget* NewComboboxFromModel(ComboboxModel* model) { return combobox; } +void LabelRealized(GtkWidget* label, gpointer unused) { + gtk_label_set_width_chars( + GTK_LABEL(label), + gtk_util::GetCharacterWidthForPixels(label, kWrapWidth)); +} + //////////////////////////////////////////////////////////////////////////////// // AddLanguageDialog @@ -142,7 +149,8 @@ void LanguagesPageGtk::Init() { IDS_FONT_LANGUAGE_SETTING_LANGUAGES_INSTRUCTIONS).c_str()); gtk_misc_set_alignment(GTK_MISC(languages_instructions_label), 0, .5); gtk_label_set_line_wrap(GTK_LABEL(languages_instructions_label), TRUE); - gtk_widget_set_size_request(languages_instructions_label, kWrapWidth, -1); + g_signal_connect(languages_instructions_label, "realize", + G_CALLBACK(LabelRealized), NULL); gtk_box_pack_start(GTK_BOX(languages_vbox), languages_instructions_label, FALSE, FALSE, 0); |