widget/gtk/nsLookAndFeel.cpp

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* vim:expandtab:shiftwidth=4:tabstop=4:
michael@0 3 */
michael@0 4 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 5 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 7
michael@0 8 // for strtod()
michael@0 9 #include <stdlib.h>
michael@0 10
michael@0 11 #include "nsLookAndFeel.h"
michael@0 12
michael@0 13 #include <gtk/gtk.h>
michael@0 14 #include <gdk/gdk.h>
michael@0 15
michael@0 16 #include <pango/pango.h>
michael@0 17 #include <pango/pango-fontmap.h>
michael@0 18
michael@0 19 #include <fontconfig/fontconfig.h>
michael@0 20 #include "gfxPlatformGtk.h"
michael@0 21
michael@0 22 #include "gtkdrawing.h"
michael@0 23 #include "nsStyleConsts.h"
michael@0 24 #include "gfxFontConstants.h"
michael@0 25 #include "mozilla/gfx/2D.h"
michael@0 26
michael@0 27 using mozilla::LookAndFeel;
michael@0 28
michael@0 29 #define GDK_COLOR_TO_NS_RGB(c) \
michael@0 30 ((nscolor) NS_RGB(c.red>>8, c.green>>8, c.blue>>8))
michael@0 31 #define GDK_RGBA_TO_NS_RGBA(c) \
michael@0 32 ((nscolor) NS_RGBA((int)((c).red*255), (int)((c).green*255), \
michael@0 33 (int)((c).blue*255), (int)((c).alpha*255)))
michael@0 34
michael@0 35 nsLookAndFeel::nsLookAndFeel()
michael@0 36 : nsXPLookAndFeel(),
michael@0 37 #if (MOZ_WIDGET_GTK == 2)
michael@0 38 mStyle(nullptr),
michael@0 39 #else
michael@0 40 mBackgroundStyle(nullptr),
michael@0 41 mViewStyle(nullptr),
michael@0 42 mButtonStyle(nullptr),
michael@0 43 #endif
michael@0 44 mDefaultFontCached(false), mButtonFontCached(false),
michael@0 45 mFieldFontCached(false), mMenuFontCached(false)
michael@0 46 {
michael@0 47 Init();
michael@0 48 }
michael@0 49
michael@0 50 nsLookAndFeel::~nsLookAndFeel()
michael@0 51 {
michael@0 52 #if (MOZ_WIDGET_GTK == 2)
michael@0 53 g_object_unref(mStyle);
michael@0 54 #else
michael@0 55 g_object_unref(mBackgroundStyle);
michael@0 56 g_object_unref(mViewStyle);
michael@0 57 g_object_unref(mButtonStyle);
michael@0 58 #endif
michael@0 59 }
michael@0 60
michael@0 61 nsresult
michael@0 62 nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
michael@0 63 {
michael@0 64 #if (MOZ_WIDGET_GTK == 3)
michael@0 65 GdkRGBA gdk_color;
michael@0 66 #endif
michael@0 67 nsresult res = NS_OK;
michael@0 68
michael@0 69 switch (aID) {
michael@0 70 // These colors don't seem to be used for anything anymore in Mozilla
michael@0 71 // (except here at least TextSelectBackground and TextSelectForeground)
michael@0 72 // The CSS2 colors below are used.
michael@0 73 #if (MOZ_WIDGET_GTK == 2)
michael@0 74 case eColorID_WindowBackground:
michael@0 75 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]);
michael@0 76 break;
michael@0 77 case eColorID_WindowForeground:
michael@0 78 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]);
michael@0 79 break;
michael@0 80 case eColorID_WidgetBackground:
michael@0 81 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
michael@0 82 break;
michael@0 83 case eColorID_WidgetForeground:
michael@0 84 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
michael@0 85 break;
michael@0 86 case eColorID_WidgetSelectBackground:
michael@0 87 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]);
michael@0 88 break;
michael@0 89 case eColorID_WidgetSelectForeground:
michael@0 90 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_SELECTED]);
michael@0 91 break;
michael@0 92 #else
michael@0 93 case eColorID_WindowBackground:
michael@0 94 case eColorID_WidgetBackground:
michael@0 95 case eColorID_TextBackground:
michael@0 96 case eColorID_activecaption: // active window caption background
michael@0 97 case eColorID_appworkspace: // MDI background color
michael@0 98 case eColorID_background: // desktop background
michael@0 99 case eColorID_window:
michael@0 100 case eColorID_windowframe:
michael@0 101 case eColorID__moz_dialog:
michael@0 102 aColor = sMozWindowBackground;
michael@0 103 break;
michael@0 104 case eColorID_WindowForeground:
michael@0 105 case eColorID_WidgetForeground:
michael@0 106 case eColorID_TextForeground:
michael@0 107 case eColorID_captiontext: // text in active window caption, size box, and scrollbar arrow box (!)
michael@0 108 case eColorID_windowtext:
michael@0 109 case eColorID__moz_dialogtext:
michael@0 110 aColor = sMozWindowText;
michael@0 111 break;
michael@0 112 case eColorID_WidgetSelectBackground:
michael@0 113 case eColorID_TextSelectBackground:
michael@0 114 case eColorID_IMESelectedRawTextBackground:
michael@0 115 case eColorID_IMESelectedConvertedTextBackground:
michael@0 116 case eColorID__moz_dragtargetzone:
michael@0 117 aColor = sMozWindowSelectedBackground;
michael@0 118 break;
michael@0 119 case eColorID_WidgetSelectForeground:
michael@0 120 case eColorID_TextSelectForeground:
michael@0 121 case eColorID_IMESelectedRawTextForeground:
michael@0 122 case eColorID_IMESelectedConvertedTextForeground:
michael@0 123 aColor = sMozWindowSelectedText;
michael@0 124 break;
michael@0 125 #endif
michael@0 126 case eColorID_Widget3DHighlight:
michael@0 127 aColor = NS_RGB(0xa0,0xa0,0xa0);
michael@0 128 break;
michael@0 129 case eColorID_Widget3DShadow:
michael@0 130 aColor = NS_RGB(0x40,0x40,0x40);
michael@0 131 break;
michael@0 132 #if (MOZ_WIDGET_GTK == 2)
michael@0 133 case eColorID_TextBackground:
michael@0 134 // not used?
michael@0 135 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]);
michael@0 136 break;
michael@0 137 case eColorID_TextForeground:
michael@0 138 // not used?
michael@0 139 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]);
michael@0 140 break;
michael@0 141 case eColorID_TextSelectBackground:
michael@0 142 case eColorID_IMESelectedRawTextBackground:
michael@0 143 case eColorID_IMESelectedConvertedTextBackground:
michael@0 144 // still used
michael@0 145 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_SELECTED]);
michael@0 146 break;
michael@0 147 case eColorID_TextSelectForeground:
michael@0 148 case eColorID_IMESelectedRawTextForeground:
michael@0 149 case eColorID_IMESelectedConvertedTextForeground:
michael@0 150 // still used
michael@0 151 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_SELECTED]);
michael@0 152 break;
michael@0 153 #endif
michael@0 154 case eColorID_IMERawInputBackground:
michael@0 155 case eColorID_IMEConvertedTextBackground:
michael@0 156 aColor = NS_TRANSPARENT;
michael@0 157 break;
michael@0 158 case eColorID_IMERawInputForeground:
michael@0 159 case eColorID_IMEConvertedTextForeground:
michael@0 160 aColor = NS_SAME_AS_FOREGROUND_COLOR;
michael@0 161 break;
michael@0 162 case eColorID_IMERawInputUnderline:
michael@0 163 case eColorID_IMEConvertedTextUnderline:
michael@0 164 aColor = NS_SAME_AS_FOREGROUND_COLOR;
michael@0 165 break;
michael@0 166 case eColorID_IMESelectedRawTextUnderline:
michael@0 167 case eColorID_IMESelectedConvertedTextUnderline:
michael@0 168 aColor = NS_TRANSPARENT;
michael@0 169 break;
michael@0 170 case eColorID_SpellCheckerUnderline:
michael@0 171 aColor = NS_RGB(0xff, 0, 0);
michael@0 172 break;
michael@0 173
michael@0 174 #if (MOZ_WIDGET_GTK == 2)
michael@0 175 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
michael@0 176 case eColorID_activeborder:
michael@0 177 // active window border
michael@0 178 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
michael@0 179 break;
michael@0 180 case eColorID_activecaption:
michael@0 181 // active window caption background
michael@0 182 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
michael@0 183 break;
michael@0 184 case eColorID_appworkspace:
michael@0 185 // MDI background color
michael@0 186 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
michael@0 187 break;
michael@0 188 case eColorID_background:
michael@0 189 // desktop background
michael@0 190 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
michael@0 191 break;
michael@0 192 case eColorID_captiontext:
michael@0 193 // text in active window caption, size box, and scrollbar arrow box (!)
michael@0 194 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
michael@0 195 break;
michael@0 196 case eColorID_graytext:
michael@0 197 // disabled text in windows, menus, etc.
michael@0 198 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_INSENSITIVE]);
michael@0 199 break;
michael@0 200 case eColorID_highlight:
michael@0 201 // background of selected item
michael@0 202 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_SELECTED]);
michael@0 203 break;
michael@0 204 case eColorID_highlighttext:
michael@0 205 // text of selected item
michael@0 206 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_SELECTED]);
michael@0 207 break;
michael@0 208 case eColorID_inactiveborder:
michael@0 209 // inactive window border
michael@0 210 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
michael@0 211 break;
michael@0 212 case eColorID_inactivecaption:
michael@0 213 // inactive window caption
michael@0 214 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_INSENSITIVE]);
michael@0 215 break;
michael@0 216 case eColorID_inactivecaptiontext:
michael@0 217 // text in inactive window caption
michael@0 218 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_INSENSITIVE]);
michael@0 219 break;
michael@0 220 #else
michael@0 221 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
michael@0 222 case eColorID_activeborder:
michael@0 223 // active window border
michael@0 224 gtk_style_context_get_border_color(mBackgroundStyle,
michael@0 225 GTK_STATE_FLAG_NORMAL, &gdk_color);
michael@0 226 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
michael@0 227 break;
michael@0 228 case eColorID_inactiveborder:
michael@0 229 // inactive window border
michael@0 230 gtk_style_context_get_border_color(mBackgroundStyle,
michael@0 231 GTK_STATE_FLAG_INSENSITIVE,
michael@0 232 &gdk_color);
michael@0 233 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
michael@0 234 break;
michael@0 235 case eColorID_graytext: // disabled text in windows, menus, etc.
michael@0 236 case eColorID_inactivecaptiontext: // text in inactive window caption
michael@0 237 gtk_style_context_get_color(mBackgroundStyle,
michael@0 238 GTK_STATE_FLAG_INSENSITIVE, &gdk_color);
michael@0 239 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
michael@0 240 break;
michael@0 241 case eColorID_highlight: // preference selected item,
michael@0 242 // background of selected item
michael@0 243 gtk_style_context_get_background_color(mViewStyle,
michael@0 244 GTK_STATE_FLAG_SELECTED,
michael@0 245 &gdk_color);
michael@0 246 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
michael@0 247 break;
michael@0 248 case eColorID_highlighttext:
michael@0 249 // text of selected item
michael@0 250 gtk_style_context_get_color(mViewStyle,
michael@0 251 GTK_STATE_FLAG_SELECTED, &gdk_color);
michael@0 252 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
michael@0 253 break;
michael@0 254 case eColorID_inactivecaption:
michael@0 255 // inactive window caption
michael@0 256 gtk_style_context_get_background_color(mBackgroundStyle,
michael@0 257 GTK_STATE_FLAG_INSENSITIVE,
michael@0 258 &gdk_color);
michael@0 259 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
michael@0 260 break;
michael@0 261 #endif
michael@0 262 case eColorID_infobackground:
michael@0 263 // tooltip background color
michael@0 264 aColor = sInfoBackground;
michael@0 265 break;
michael@0 266 case eColorID_infotext:
michael@0 267 // tooltip text color
michael@0 268 aColor = sInfoText;
michael@0 269 break;
michael@0 270 case eColorID_menu:
michael@0 271 // menu background
michael@0 272 aColor = sMenuBackground;
michael@0 273 break;
michael@0 274 case eColorID_menutext:
michael@0 275 // menu text
michael@0 276 aColor = sMenuText;
michael@0 277 break;
michael@0 278 case eColorID_scrollbar:
michael@0 279 // scrollbar gray area
michael@0 280 #if (MOZ_WIDGET_GTK == 2)
michael@0 281 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_ACTIVE]);
michael@0 282 #else
michael@0 283 aColor = sMozScrollbar;
michael@0 284 #endif
michael@0 285 break;
michael@0 286
michael@0 287 case eColorID_threedface:
michael@0 288 case eColorID_buttonface:
michael@0 289 // 3-D face color
michael@0 290 aColor = sButtonBackground;
michael@0 291 break;
michael@0 292
michael@0 293 case eColorID_buttontext:
michael@0 294 // text on push buttons
michael@0 295 aColor = sButtonText;
michael@0 296 break;
michael@0 297
michael@0 298 case eColorID_buttonhighlight:
michael@0 299 // 3-D highlighted edge color
michael@0 300 case eColorID_threedhighlight:
michael@0 301 // 3-D highlighted outer edge color
michael@0 302 aColor = sButtonOuterLightBorder;
michael@0 303 break;
michael@0 304
michael@0 305 case eColorID_threedlightshadow:
michael@0 306 // 3-D highlighted inner edge color
michael@0 307 aColor = sButtonBackground; // always same as background in GTK code
michael@0 308 break;
michael@0 309
michael@0 310 case eColorID_buttonshadow:
michael@0 311 // 3-D shadow edge color
michael@0 312 case eColorID_threedshadow:
michael@0 313 // 3-D shadow inner edge color
michael@0 314 aColor = sButtonInnerDarkBorder;
michael@0 315 break;
michael@0 316
michael@0 317 #if (MOZ_WIDGET_GTK == 2)
michael@0 318 case eColorID_threeddarkshadow:
michael@0 319 // 3-D shadow outer edge color
michael@0 320 aColor = GDK_COLOR_TO_NS_RGB(mStyle->black);
michael@0 321 break;
michael@0 322
michael@0 323 case eColorID_window:
michael@0 324 case eColorID_windowframe:
michael@0 325 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
michael@0 326 break;
michael@0 327
michael@0 328 case eColorID_windowtext:
michael@0 329 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
michael@0 330 break;
michael@0 331
michael@0 332 case eColorID__moz_eventreerow:
michael@0 333 case eColorID__moz_field:
michael@0 334 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]);
michael@0 335 break;
michael@0 336 case eColorID__moz_fieldtext:
michael@0 337 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]);
michael@0 338 break;
michael@0 339 case eColorID__moz_dialog:
michael@0 340 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
michael@0 341 break;
michael@0 342 case eColorID__moz_dialogtext:
michael@0 343 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
michael@0 344 break;
michael@0 345 case eColorID__moz_dragtargetzone:
michael@0 346 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]);
michael@0 347 break;
michael@0 348 case eColorID__moz_buttondefault:
michael@0 349 // default button border color
michael@0 350 aColor = GDK_COLOR_TO_NS_RGB(mStyle->black);
michael@0 351 break;
michael@0 352 case eColorID__moz_buttonhoverface:
michael@0 353 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_PRELIGHT]);
michael@0 354 break;
michael@0 355 case eColorID__moz_buttonhovertext:
michael@0 356 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_PRELIGHT]);
michael@0 357 break;
michael@0 358 case eColorID__moz_cellhighlight:
michael@0 359 case eColorID__moz_html_cellhighlight:
michael@0 360 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_ACTIVE]);
michael@0 361 break;
michael@0 362 case eColorID__moz_cellhighlighttext:
michael@0 363 case eColorID__moz_html_cellhighlighttext:
michael@0 364 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_ACTIVE]);
michael@0 365 break;
michael@0 366 #else
michael@0 367 case eColorID_threeddarkshadow:
michael@0 368 // Hardcode to black
michael@0 369 aColor = NS_RGB(0x00,0x00,0x00);;
michael@0 370 break;
michael@0 371
michael@0 372 case eColorID__moz_eventreerow:
michael@0 373 case eColorID__moz_field:
michael@0 374 aColor = sMozFieldBackground;
michael@0 375 break;
michael@0 376 case eColorID__moz_fieldtext:
michael@0 377 aColor = sMozFieldText;
michael@0 378 break;
michael@0 379 case eColorID__moz_buttondefault:
michael@0 380 // default button border color
michael@0 381 gtk_style_context_get_border_color(mButtonStyle,
michael@0 382 GTK_STATE_FLAG_NORMAL, &gdk_color);
michael@0 383 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
michael@0 384 break;
michael@0 385 case eColorID__moz_buttonhoverface:
michael@0 386 gtk_style_context_get_background_color(mButtonStyle,
michael@0 387 GTK_STATE_FLAG_PRELIGHT,
michael@0 388 &gdk_color);
michael@0 389 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
michael@0 390 break;
michael@0 391 case eColorID__moz_buttonhovertext:
michael@0 392 aColor = sButtonHoverText;
michael@0 393 break;
michael@0 394 case eColorID__moz_cellhighlight:
michael@0 395 case eColorID__moz_html_cellhighlight:
michael@0 396 gtk_style_context_get_background_color(mViewStyle,
michael@0 397 GTK_STATE_FLAG_SELECTED,
michael@0 398 &gdk_color);
michael@0 399 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
michael@0 400 break;
michael@0 401 case eColorID__moz_cellhighlighttext:
michael@0 402 case eColorID__moz_html_cellhighlighttext:
michael@0 403 gtk_style_context_get_color(mViewStyle,
michael@0 404 GTK_STATE_FLAG_SELECTED, &gdk_color);
michael@0 405 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
michael@0 406 break;
michael@0 407 #endif
michael@0 408 case eColorID__moz_menuhover:
michael@0 409 aColor = sMenuHover;
michael@0 410 break;
michael@0 411 case eColorID__moz_menuhovertext:
michael@0 412 aColor = sMenuHoverText;
michael@0 413 break;
michael@0 414 case eColorID__moz_oddtreerow:
michael@0 415 aColor = sOddCellBackground;
michael@0 416 break;
michael@0 417 case eColorID__moz_nativehyperlinktext:
michael@0 418 aColor = sNativeHyperLinkText;
michael@0 419 break;
michael@0 420 case eColorID__moz_comboboxtext:
michael@0 421 aColor = sComboBoxText;
michael@0 422 break;
michael@0 423 case eColorID__moz_combobox:
michael@0 424 aColor = sComboBoxBackground;
michael@0 425 break;
michael@0 426 case eColorID__moz_menubartext:
michael@0 427 aColor = sMenuBarText;
michael@0 428 break;
michael@0 429 case eColorID__moz_menubarhovertext:
michael@0 430 aColor = sMenuBarHoverText;
michael@0 431 break;
michael@0 432 default:
michael@0 433 /* default color is BLACK */
michael@0 434 aColor = 0;
michael@0 435 res = NS_ERROR_FAILURE;
michael@0 436 break;
michael@0 437 }
michael@0 438
michael@0 439 return res;
michael@0 440 }
michael@0 441
michael@0 442 #if (MOZ_WIDGET_GTK == 2)
michael@0 443 static void darken_gdk_color(GdkColor *src, GdkColor *dest)
michael@0 444 {
michael@0 445 gdouble red;
michael@0 446 gdouble green;
michael@0 447 gdouble blue;
michael@0 448
michael@0 449 red = (gdouble) src->red / 65535.0;
michael@0 450 green = (gdouble) src->green / 65535.0;
michael@0 451 blue = (gdouble) src->blue / 65535.0;
michael@0 452
michael@0 453 red *= 0.93;
michael@0 454 green *= 0.93;
michael@0 455 blue *= 0.93;
michael@0 456
michael@0 457 dest->red = red * 65535.0;
michael@0 458 dest->green = green * 65535.0;
michael@0 459 dest->blue = blue * 65535.0;
michael@0 460 }
michael@0 461 #endif
michael@0 462
michael@0 463 static int32_t CheckWidgetStyle(GtkWidget* aWidget, const char* aStyle, int32_t aResult) {
michael@0 464 gboolean value = FALSE;
michael@0 465 gtk_widget_style_get(aWidget, aStyle, &value, nullptr);
michael@0 466 return value ? aResult : 0;
michael@0 467 }
michael@0 468
michael@0 469 static int32_t ConvertGTKStepperStyleToMozillaScrollArrowStyle(GtkWidget* aWidget)
michael@0 470 {
michael@0 471 if (!aWidget)
michael@0 472 return mozilla::LookAndFeel::eScrollArrowStyle_Single;
michael@0 473
michael@0 474 return
michael@0 475 CheckWidgetStyle(aWidget, "has-backward-stepper",
michael@0 476 mozilla::LookAndFeel::eScrollArrow_StartBackward) |
michael@0 477 CheckWidgetStyle(aWidget, "has-forward-stepper",
michael@0 478 mozilla::LookAndFeel::eScrollArrow_EndForward) |
michael@0 479 CheckWidgetStyle(aWidget, "has-secondary-backward-stepper",
michael@0 480 mozilla::LookAndFeel::eScrollArrow_EndBackward) |
michael@0 481 CheckWidgetStyle(aWidget, "has-secondary-forward-stepper",
michael@0 482 mozilla::LookAndFeel::eScrollArrow_StartForward);
michael@0 483 }
michael@0 484
michael@0 485 nsresult
michael@0 486 nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
michael@0 487 {
michael@0 488 nsresult res = NS_OK;
michael@0 489
michael@0 490 // Set these before they can get overrided in the nsXPLookAndFeel.
michael@0 491 switch (aID) {
michael@0 492 case eIntID_ScrollButtonLeftMouseButtonAction:
michael@0 493 aResult = 0;
michael@0 494 return NS_OK;
michael@0 495 case eIntID_ScrollButtonMiddleMouseButtonAction:
michael@0 496 aResult = 1;
michael@0 497 return NS_OK;
michael@0 498 case eIntID_ScrollButtonRightMouseButtonAction:
michael@0 499 aResult = 2;
michael@0 500 return NS_OK;
michael@0 501 default:
michael@0 502 break;
michael@0 503 }
michael@0 504
michael@0 505 res = nsXPLookAndFeel::GetIntImpl(aID, aResult);
michael@0 506 if (NS_SUCCEEDED(res))
michael@0 507 return res;
michael@0 508 res = NS_OK;
michael@0 509
michael@0 510 switch (aID) {
michael@0 511 case eIntID_CaretBlinkTime:
michael@0 512 {
michael@0 513 GtkSettings *settings;
michael@0 514 gint blink_time;
michael@0 515 gboolean blink;
michael@0 516
michael@0 517 settings = gtk_settings_get_default ();
michael@0 518 g_object_get (settings,
michael@0 519 "gtk-cursor-blink-time", &blink_time,
michael@0 520 "gtk-cursor-blink", &blink,
michael@0 521 nullptr);
michael@0 522
michael@0 523 if (blink)
michael@0 524 aResult = (int32_t) blink_time;
michael@0 525 else
michael@0 526 aResult = 0;
michael@0 527 break;
michael@0 528 }
michael@0 529 case eIntID_CaretWidth:
michael@0 530 aResult = 1;
michael@0 531 break;
michael@0 532 case eIntID_ShowCaretDuringSelection:
michael@0 533 aResult = 0;
michael@0 534 break;
michael@0 535 case eIntID_SelectTextfieldsOnKeyFocus:
michael@0 536 {
michael@0 537 GtkWidget *entry;
michael@0 538 GtkSettings *settings;
michael@0 539 gboolean select_on_focus;
michael@0 540
michael@0 541 entry = gtk_entry_new();
michael@0 542 g_object_ref_sink(entry);
michael@0 543 settings = gtk_widget_get_settings(entry);
michael@0 544 g_object_get(settings,
michael@0 545 "gtk-entry-select-on-focus",
michael@0 546 &select_on_focus,
michael@0 547 nullptr);
michael@0 548
michael@0 549 if(select_on_focus)
michael@0 550 aResult = 1;
michael@0 551 else
michael@0 552 aResult = 0;
michael@0 553
michael@0 554 gtk_widget_destroy(entry);
michael@0 555 g_object_unref(entry);
michael@0 556 }
michael@0 557 break;
michael@0 558 case eIntID_SubmenuDelay:
michael@0 559 {
michael@0 560 GtkSettings *settings;
michael@0 561 gint delay;
michael@0 562
michael@0 563 settings = gtk_settings_get_default ();
michael@0 564 g_object_get (settings, "gtk-menu-popup-delay", &delay, nullptr);
michael@0 565 aResult = (int32_t) delay;
michael@0 566 break;
michael@0 567 }
michael@0 568 case eIntID_TooltipDelay:
michael@0 569 {
michael@0 570 aResult = 500;
michael@0 571 break;
michael@0 572 }
michael@0 573 case eIntID_MenusCanOverlapOSBar:
michael@0 574 // we want XUL popups to be able to overlap the task bar.
michael@0 575 aResult = 1;
michael@0 576 break;
michael@0 577 case eIntID_SkipNavigatingDisabledMenuItem:
michael@0 578 aResult = 1;
michael@0 579 break;
michael@0 580 case eIntID_DragThresholdX:
michael@0 581 case eIntID_DragThresholdY:
michael@0 582 {
michael@0 583 GtkWidget* box = gtk_hbox_new(FALSE, 5);
michael@0 584 gint threshold = 0;
michael@0 585 g_object_get(gtk_widget_get_settings(box),
michael@0 586 "gtk-dnd-drag-threshold", &threshold,
michael@0 587 nullptr);
michael@0 588 g_object_ref_sink(box);
michael@0 589
michael@0 590 aResult = threshold;
michael@0 591 }
michael@0 592 break;
michael@0 593 case eIntID_ScrollArrowStyle:
michael@0 594 moz_gtk_init();
michael@0 595 aResult =
michael@0 596 ConvertGTKStepperStyleToMozillaScrollArrowStyle(moz_gtk_get_scrollbar_widget());
michael@0 597 break;
michael@0 598 case eIntID_ScrollSliderStyle:
michael@0 599 aResult = eScrollThumbStyle_Proportional;
michael@0 600 break;
michael@0 601 case eIntID_TreeOpenDelay:
michael@0 602 aResult = 1000;
michael@0 603 break;
michael@0 604 case eIntID_TreeCloseDelay:
michael@0 605 aResult = 1000;
michael@0 606 break;
michael@0 607 case eIntID_TreeLazyScrollDelay:
michael@0 608 aResult = 150;
michael@0 609 break;
michael@0 610 case eIntID_TreeScrollDelay:
michael@0 611 aResult = 100;
michael@0 612 break;
michael@0 613 case eIntID_TreeScrollLinesMax:
michael@0 614 aResult = 3;
michael@0 615 break;
michael@0 616 case eIntID_DWMCompositor:
michael@0 617 case eIntID_WindowsClassic:
michael@0 618 case eIntID_WindowsDefaultTheme:
michael@0 619 case eIntID_WindowsThemeIdentifier:
michael@0 620 case eIntID_OperatingSystemVersionIdentifier:
michael@0 621 aResult = 0;
michael@0 622 res = NS_ERROR_NOT_IMPLEMENTED;
michael@0 623 break;
michael@0 624 case eIntID_TouchEnabled:
michael@0 625 aResult = 0;
michael@0 626 res = NS_ERROR_NOT_IMPLEMENTED;
michael@0 627 break;
michael@0 628 case eIntID_MacGraphiteTheme:
michael@0 629 case eIntID_MacLionTheme:
michael@0 630 aResult = 0;
michael@0 631 res = NS_ERROR_NOT_IMPLEMENTED;
michael@0 632 break;
michael@0 633 case eIntID_AlertNotificationOrigin:
michael@0 634 aResult = NS_ALERT_TOP;
michael@0 635 break;
michael@0 636 case eIntID_IMERawInputUnderlineStyle:
michael@0 637 case eIntID_IMEConvertedTextUnderlineStyle:
michael@0 638 aResult = NS_STYLE_TEXT_DECORATION_STYLE_SOLID;
michael@0 639 break;
michael@0 640 case eIntID_IMESelectedRawTextUnderlineStyle:
michael@0 641 case eIntID_IMESelectedConvertedTextUnderline:
michael@0 642 aResult = NS_STYLE_TEXT_DECORATION_STYLE_NONE;
michael@0 643 break;
michael@0 644 case eIntID_SpellCheckerUnderlineStyle:
michael@0 645 aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY;
michael@0 646 break;
michael@0 647 case eIntID_ImagesInMenus:
michael@0 648 aResult = moz_gtk_images_in_menus();
michael@0 649 break;
michael@0 650 case eIntID_ImagesInButtons:
michael@0 651 aResult = moz_gtk_images_in_buttons();
michael@0 652 break;
michael@0 653 case eIntID_MenuBarDrag:
michael@0 654 aResult = sMenuSupportsDrag;
michael@0 655 break;
michael@0 656 case eIntID_ScrollbarButtonAutoRepeatBehavior:
michael@0 657 aResult = 1;
michael@0 658 break;
michael@0 659 case eIntID_SwipeAnimationEnabled:
michael@0 660 aResult = 0;
michael@0 661 break;
michael@0 662 case eIntID_ColorPickerAvailable:
michael@0 663 aResult = 1;
michael@0 664 break;
michael@0 665 default:
michael@0 666 aResult = 0;
michael@0 667 res = NS_ERROR_FAILURE;
michael@0 668 }
michael@0 669
michael@0 670 return res;
michael@0 671 }
michael@0 672
michael@0 673 nsresult
michael@0 674 nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult)
michael@0 675 {
michael@0 676 nsresult res = NS_OK;
michael@0 677 res = nsXPLookAndFeel::GetFloatImpl(aID, aResult);
michael@0 678 if (NS_SUCCEEDED(res))
michael@0 679 return res;
michael@0 680 res = NS_OK;
michael@0 681
michael@0 682 switch (aID) {
michael@0 683 case eFloatID_IMEUnderlineRelativeSize:
michael@0 684 aResult = 1.0f;
michael@0 685 break;
michael@0 686 case eFloatID_SpellCheckerUnderlineRelativeSize:
michael@0 687 aResult = 1.0f;
michael@0 688 break;
michael@0 689 case eFloatID_CaretAspectRatio:
michael@0 690 aResult = sCaretRatio;
michael@0 691 break;
michael@0 692 default:
michael@0 693 aResult = -1.0;
michael@0 694 res = NS_ERROR_FAILURE;
michael@0 695 }
michael@0 696 return res;
michael@0 697 }
michael@0 698
michael@0 699 static void
michael@0 700 GetSystemFontInfo(GtkWidget *aWidget,
michael@0 701 nsString *aFontName,
michael@0 702 gfxFontStyle *aFontStyle)
michael@0 703 {
michael@0 704 GtkSettings *settings = gtk_widget_get_settings(aWidget);
michael@0 705
michael@0 706 aFontStyle->style = NS_FONT_STYLE_NORMAL;
michael@0 707
michael@0 708 gchar *fontname;
michael@0 709 g_object_get(settings, "gtk-font-name", &fontname, nullptr);
michael@0 710
michael@0 711 PangoFontDescription *desc;
michael@0 712 desc = pango_font_description_from_string(fontname);
michael@0 713
michael@0 714 aFontStyle->systemFont = true;
michael@0 715
michael@0 716 g_free(fontname);
michael@0 717
michael@0 718 NS_NAMED_LITERAL_STRING(quote, "\"");
michael@0 719 NS_ConvertUTF8toUTF16 family(pango_font_description_get_family(desc));
michael@0 720 *aFontName = quote + family + quote;
michael@0 721
michael@0 722 aFontStyle->weight = pango_font_description_get_weight(desc);
michael@0 723
michael@0 724 // FIXME: Set aFontStyle->stretch correctly!
michael@0 725 aFontStyle->stretch = NS_FONT_STRETCH_NORMAL;
michael@0 726
michael@0 727 float size = float(pango_font_description_get_size(desc)) / PANGO_SCALE;
michael@0 728
michael@0 729 // |size| is now either pixels or pango-points (not Mozilla-points!)
michael@0 730
michael@0 731 if (!pango_font_description_get_size_is_absolute(desc)) {
michael@0 732 // |size| is in pango-points, so convert to pixels.
michael@0 733 size *= float(gfxPlatformGtk::GetDPI()) / POINTS_PER_INCH_FLOAT;
michael@0 734 }
michael@0 735
michael@0 736 // |size| is now pixels
michael@0 737
michael@0 738 aFontStyle->size = size;
michael@0 739
michael@0 740 pango_font_description_free(desc);
michael@0 741 }
michael@0 742
michael@0 743 static void
michael@0 744 GetSystemFontInfo(LookAndFeel::FontID aID,
michael@0 745 nsString *aFontName,
michael@0 746 gfxFontStyle *aFontStyle)
michael@0 747 {
michael@0 748 if (aID == LookAndFeel::eFont_Widget) {
michael@0 749 GtkWidget *label = gtk_label_new("M");
michael@0 750 GtkWidget *parent = gtk_fixed_new();
michael@0 751 GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
michael@0 752
michael@0 753 gtk_container_add(GTK_CONTAINER(parent), label);
michael@0 754 gtk_container_add(GTK_CONTAINER(window), parent);
michael@0 755
michael@0 756 gtk_widget_ensure_style(label);
michael@0 757 GetSystemFontInfo(label, aFontName, aFontStyle);
michael@0 758 gtk_widget_destroy(window); // no unref, windows are different
michael@0 759
michael@0 760 } else if (aID == LookAndFeel::eFont_Button) {
michael@0 761 GtkWidget *label = gtk_label_new("M");
michael@0 762 GtkWidget *parent = gtk_fixed_new();
michael@0 763 GtkWidget *button = gtk_button_new();
michael@0 764 GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
michael@0 765
michael@0 766 gtk_container_add(GTK_CONTAINER(button), label);
michael@0 767 gtk_container_add(GTK_CONTAINER(parent), button);
michael@0 768 gtk_container_add(GTK_CONTAINER(window), parent);
michael@0 769
michael@0 770 gtk_widget_ensure_style(label);
michael@0 771 GetSystemFontInfo(label, aFontName, aFontStyle);
michael@0 772 gtk_widget_destroy(window); // no unref, windows are different
michael@0 773
michael@0 774 } else if (aID == LookAndFeel::eFont_Field) {
michael@0 775 GtkWidget *entry = gtk_entry_new();
michael@0 776 GtkWidget *parent = gtk_fixed_new();
michael@0 777 GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
michael@0 778
michael@0 779 gtk_container_add(GTK_CONTAINER(parent), entry);
michael@0 780 gtk_container_add(GTK_CONTAINER(window), parent);
michael@0 781
michael@0 782 gtk_widget_ensure_style(entry);
michael@0 783 GetSystemFontInfo(entry, aFontName, aFontStyle);
michael@0 784 gtk_widget_destroy(window); // no unref, windows are different
michael@0 785
michael@0 786 } else {
michael@0 787 NS_ABORT_IF_FALSE(aID == LookAndFeel::eFont_Menu, "unexpected font ID");
michael@0 788 GtkWidget *accel_label = gtk_accel_label_new("M");
michael@0 789 GtkWidget *menuitem = gtk_menu_item_new();
michael@0 790 GtkWidget *menu = gtk_menu_new();
michael@0 791 g_object_ref_sink(menu);
michael@0 792
michael@0 793 gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
michael@0 794 gtk_menu_shell_append((GtkMenuShell *)GTK_MENU(menu), menuitem);
michael@0 795
michael@0 796 gtk_widget_ensure_style(accel_label);
michael@0 797 GetSystemFontInfo(accel_label, aFontName, aFontStyle);
michael@0 798 g_object_unref(menu);
michael@0 799 }
michael@0 800 }
michael@0 801
michael@0 802 bool
michael@0 803 nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName,
michael@0 804 gfxFontStyle& aFontStyle,
michael@0 805 float aDevPixPerCSSPixel)
michael@0 806 {
michael@0 807 nsString *cachedFontName = nullptr;
michael@0 808 gfxFontStyle *cachedFontStyle = nullptr;
michael@0 809 bool *isCached = nullptr;
michael@0 810
michael@0 811 switch (aID) {
michael@0 812 case eFont_Menu: // css2
michael@0 813 case eFont_PullDownMenu: // css3
michael@0 814 cachedFontName = &mMenuFontName;
michael@0 815 cachedFontStyle = &mMenuFontStyle;
michael@0 816 isCached = &mMenuFontCached;
michael@0 817 aID = eFont_Menu;
michael@0 818 break;
michael@0 819
michael@0 820 case eFont_Field: // css3
michael@0 821 case eFont_List: // css3
michael@0 822 cachedFontName = &mFieldFontName;
michael@0 823 cachedFontStyle = &mFieldFontStyle;
michael@0 824 isCached = &mFieldFontCached;
michael@0 825 aID = eFont_Field;
michael@0 826 break;
michael@0 827
michael@0 828 case eFont_Button: // css3
michael@0 829 cachedFontName = &mButtonFontName;
michael@0 830 cachedFontStyle = &mButtonFontStyle;
michael@0 831 isCached = &mButtonFontCached;
michael@0 832 break;
michael@0 833
michael@0 834 case eFont_Caption: // css2
michael@0 835 case eFont_Icon: // css2
michael@0 836 case eFont_MessageBox: // css2
michael@0 837 case eFont_SmallCaption: // css2
michael@0 838 case eFont_StatusBar: // css2
michael@0 839 case eFont_Window: // css3
michael@0 840 case eFont_Document: // css3
michael@0 841 case eFont_Workspace: // css3
michael@0 842 case eFont_Desktop: // css3
michael@0 843 case eFont_Info: // css3
michael@0 844 case eFont_Dialog: // css3
michael@0 845 case eFont_Tooltips: // moz
michael@0 846 case eFont_Widget: // moz
michael@0 847 cachedFontName = &mDefaultFontName;
michael@0 848 cachedFontStyle = &mDefaultFontStyle;
michael@0 849 isCached = &mDefaultFontCached;
michael@0 850 aID = eFont_Widget;
michael@0 851 break;
michael@0 852 }
michael@0 853
michael@0 854 if (!*isCached) {
michael@0 855 GetSystemFontInfo(aID, cachedFontName, cachedFontStyle);
michael@0 856 *isCached = true;
michael@0 857 }
michael@0 858
michael@0 859 aFontName = *cachedFontName;
michael@0 860 aFontStyle = *cachedFontStyle;
michael@0 861 return true;
michael@0 862 }
michael@0 863
michael@0 864 #if (MOZ_WIDGET_GTK == 3)
michael@0 865 static GtkStyleContext*
michael@0 866 create_context(GtkWidgetPath *path)
michael@0 867 {
michael@0 868 GtkStyleContext *style = gtk_style_context_new();
michael@0 869 gtk_style_context_set_path(style, path);
michael@0 870 return(style);
michael@0 871 }
michael@0 872 #endif
michael@0 873
michael@0 874 void
michael@0 875 nsLookAndFeel::Init()
michael@0 876 {
michael@0 877 GdkColor colorValue;
michael@0 878 GdkColor *colorValuePtr;
michael@0 879
michael@0 880 #if (MOZ_WIDGET_GTK == 2)
michael@0 881 NS_ASSERTION(!mStyle, "already initialized");
michael@0 882 // GtkInvisibles come with a refcount that is not floating
michael@0 883 // (since their initialization code calls g_object_ref_sink) and
michael@0 884 // their destroy code releases that reference (which means they
michael@0 885 // have to be explicitly destroyed, since calling unref enough
michael@0 886 // to cause destruction would lead to *another* unref).
michael@0 887 // However, this combination means that it's actually still ok
michael@0 888 // to use the normal pattern, which is to g_object_ref_sink
michael@0 889 // after construction, and then destroy *and* unref when we're
michael@0 890 // done. (Though we could skip the g_object_ref_sink and the
michael@0 891 // corresponding g_object_unref, but that's particular to
michael@0 892 // GtkInvisibles and GtkWindows.)
michael@0 893 GtkWidget *widget = gtk_invisible_new();
michael@0 894 g_object_ref_sink(widget); // effectively g_object_ref (see above)
michael@0 895
michael@0 896 gtk_widget_ensure_style(widget);
michael@0 897 mStyle = gtk_style_copy(gtk_widget_get_style(widget));
michael@0 898
michael@0 899 gtk_widget_destroy(widget);
michael@0 900 g_object_unref(widget);
michael@0 901
michael@0 902 // tooltip foreground and background
michael@0 903 GtkStyle *style = gtk_rc_get_style_by_paths(gtk_settings_get_default(),
michael@0 904 "gtk-tooltips", "GtkWindow",
michael@0 905 GTK_TYPE_WINDOW);
michael@0 906 if (style) {
michael@0 907 sInfoBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
michael@0 908 sInfoText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
michael@0 909 }
michael@0 910
michael@0 911 // menu foreground & menu background
michael@0 912 GtkWidget *accel_label = gtk_accel_label_new("M");
michael@0 913 GtkWidget *menuitem = gtk_menu_item_new();
michael@0 914 GtkWidget *menu = gtk_menu_new();
michael@0 915
michael@0 916 g_object_ref_sink(menu);
michael@0 917
michael@0 918 gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
michael@0 919 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
michael@0 920
michael@0 921 gtk_widget_set_style(accel_label, nullptr);
michael@0 922 gtk_widget_set_style(menu, nullptr);
michael@0 923 gtk_widget_realize(menu);
michael@0 924 gtk_widget_realize(accel_label);
michael@0 925
michael@0 926 style = gtk_widget_get_style(accel_label);
michael@0 927 if (style) {
michael@0 928 sMenuText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
michael@0 929 }
michael@0 930
michael@0 931 style = gtk_widget_get_style(menu);
michael@0 932 if (style) {
michael@0 933 sMenuBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
michael@0 934 }
michael@0 935
michael@0 936 style = gtk_widget_get_style(menuitem);
michael@0 937 if (style) {
michael@0 938 sMenuHover = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_PRELIGHT]);
michael@0 939 sMenuHoverText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_PRELIGHT]);
michael@0 940 }
michael@0 941
michael@0 942 g_object_unref(menu);
michael@0 943 #else
michael@0 944 GdkRGBA color;
michael@0 945 GtkStyleContext *style;
michael@0 946
michael@0 947 // Gtk manages a screen's CSS in the settings object so we
michael@0 948 // ask Gtk to create it explicitly. Otherwise we may end up
michael@0 949 // with wrong color theme, see Bug 972382
michael@0 950 (void)gtk_settings_get_for_screen(gdk_screen_get_default());
michael@0 951
michael@0 952 GtkWidgetPath *path = gtk_widget_path_new();
michael@0 953 gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
michael@0 954
michael@0 955 mBackgroundStyle = create_context(path);
michael@0 956 gtk_style_context_add_class(mBackgroundStyle, GTK_STYLE_CLASS_BACKGROUND);
michael@0 957
michael@0 958 mViewStyle = create_context(path);
michael@0 959 gtk_style_context_add_class(mViewStyle, GTK_STYLE_CLASS_VIEW);
michael@0 960
michael@0 961 mButtonStyle = create_context(path);
michael@0 962 gtk_style_context_add_class(mButtonStyle, GTK_STYLE_CLASS_BUTTON);
michael@0 963
michael@0 964 // Scrollbar colors
michael@0 965 style = create_context(path);
michael@0 966 gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR);
michael@0 967 gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
michael@0 968 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 969 sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color);
michael@0 970 g_object_unref(style);
michael@0 971
michael@0 972 // Text colors
michael@0 973 gtk_style_context_get_background_color(mViewStyle, GTK_STATE_FLAG_NORMAL, &color);
michael@0 974 sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color);
michael@0 975 gtk_style_context_get_color(mViewStyle, GTK_STATE_FLAG_NORMAL, &color);
michael@0 976 sMozFieldText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 977
michael@0 978 // Window colors
michael@0 979 style = create_context(path);
michael@0 980 gtk_style_context_save(style);
michael@0 981 gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
michael@0 982 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 983 sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color);
michael@0 984 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 985 sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 986
michael@0 987 // Selected text and background
michael@0 988 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_SELECTED, &color);
michael@0 989 sMozWindowSelectedBackground = GDK_RGBA_TO_NS_RGBA(color);
michael@0 990 gtk_style_context_get_color(style, GTK_STATE_FLAG_SELECTED, &color);
michael@0 991 sMozWindowSelectedText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 992 gtk_style_context_restore(style);
michael@0 993
michael@0 994 // tooltip foreground and background
michael@0 995 gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
michael@0 996 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 997 sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
michael@0 998 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 999 sInfoText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1000 g_object_unref(style);
michael@0 1001
michael@0 1002 // menu foreground & menu background
michael@0 1003 GtkWidget *accel_label = gtk_accel_label_new("M");
michael@0 1004 GtkWidget *menuitem = gtk_menu_item_new();
michael@0 1005 GtkWidget *menu = gtk_menu_new();
michael@0 1006
michael@0 1007 g_object_ref_sink(menu);
michael@0 1008
michael@0 1009 gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
michael@0 1010 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
michael@0 1011
michael@0 1012 style = gtk_widget_get_style_context(accel_label);
michael@0 1013 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 1014 sMenuText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1015
michael@0 1016 style = gtk_widget_get_style_context(menu);
michael@0 1017 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 1018 sMenuBackground = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1019
michael@0 1020 style = gtk_widget_get_style_context(menuitem);
michael@0 1021 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
michael@0 1022 sMenuHover = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1023 gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
michael@0 1024 sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1025
michael@0 1026 g_object_unref(menu);
michael@0 1027 #endif
michael@0 1028
michael@0 1029 // button styles
michael@0 1030 GtkWidget *parent = gtk_fixed_new();
michael@0 1031 GtkWidget *button = gtk_button_new();
michael@0 1032 GtkWidget *label = gtk_label_new("M");
michael@0 1033 #if (MOZ_WIDGET_GTK == 2)
michael@0 1034 GtkWidget *combobox = gtk_combo_box_new();
michael@0 1035 GtkWidget *comboboxLabel = gtk_label_new("M");
michael@0 1036 gtk_container_add(GTK_CONTAINER(combobox), comboboxLabel);
michael@0 1037 #else
michael@0 1038 GtkWidget *combobox = gtk_combo_box_new_with_entry();
michael@0 1039 GtkWidget *comboboxLabel = gtk_bin_get_child(GTK_BIN(combobox));
michael@0 1040 #endif
michael@0 1041 GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
michael@0 1042 GtkWidget *treeView = gtk_tree_view_new();
michael@0 1043 GtkWidget *linkButton = gtk_link_button_new("http://example.com/");
michael@0 1044 GtkWidget *menuBar = gtk_menu_bar_new();
michael@0 1045 GtkWidget *entry = gtk_entry_new();
michael@0 1046
michael@0 1047 gtk_container_add(GTK_CONTAINER(button), label);
michael@0 1048 gtk_container_add(GTK_CONTAINER(parent), button);
michael@0 1049 gtk_container_add(GTK_CONTAINER(parent), treeView);
michael@0 1050 gtk_container_add(GTK_CONTAINER(parent), linkButton);
michael@0 1051 gtk_container_add(GTK_CONTAINER(parent), combobox);
michael@0 1052 gtk_container_add(GTK_CONTAINER(parent), menuBar);
michael@0 1053 gtk_container_add(GTK_CONTAINER(window), parent);
michael@0 1054 gtk_container_add(GTK_CONTAINER(parent), entry);
michael@0 1055
michael@0 1056 #if (MOZ_WIDGET_GTK == 2)
michael@0 1057 gtk_widget_set_style(button, nullptr);
michael@0 1058 gtk_widget_set_style(label, nullptr);
michael@0 1059 gtk_widget_set_style(treeView, nullptr);
michael@0 1060 gtk_widget_set_style(linkButton, nullptr);
michael@0 1061 gtk_widget_set_style(combobox, nullptr);
michael@0 1062 gtk_widget_set_style(comboboxLabel, nullptr);
michael@0 1063 gtk_widget_set_style(menuBar, nullptr);
michael@0 1064 gtk_widget_set_style(entry, nullptr);
michael@0 1065
michael@0 1066 gtk_widget_realize(button);
michael@0 1067 gtk_widget_realize(label);
michael@0 1068 gtk_widget_realize(treeView);
michael@0 1069 gtk_widget_realize(linkButton);
michael@0 1070 gtk_widget_realize(combobox);
michael@0 1071 gtk_widget_realize(comboboxLabel);
michael@0 1072 gtk_widget_realize(menuBar);
michael@0 1073 gtk_widget_realize(entry);
michael@0 1074
michael@0 1075 style = gtk_widget_get_style(label);
michael@0 1076 if (style) {
michael@0 1077 sButtonText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
michael@0 1078 }
michael@0 1079
michael@0 1080 style = gtk_widget_get_style(comboboxLabel);
michael@0 1081 if (style) {
michael@0 1082 sComboBoxText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
michael@0 1083 }
michael@0 1084 style = gtk_widget_get_style(combobox);
michael@0 1085 if (style) {
michael@0 1086 sComboBoxBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
michael@0 1087 }
michael@0 1088
michael@0 1089 style = gtk_widget_get_style(menuBar);
michael@0 1090 if (style) {
michael@0 1091 sMenuBarText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
michael@0 1092 sMenuBarHoverText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_SELECTED]);
michael@0 1093 }
michael@0 1094
michael@0 1095 // GTK's guide to fancy odd row background colors:
michael@0 1096 // 1) Check if a theme explicitly defines an odd row color
michael@0 1097 // 2) If not, check if it defines an even row color, and darken it
michael@0 1098 // slightly by a hardcoded value (gtkstyle.c)
michael@0 1099 // 3) If neither are defined, take the base background color and
michael@0 1100 // darken that by a hardcoded value
michael@0 1101 colorValuePtr = nullptr;
michael@0 1102 gtk_widget_style_get(treeView,
michael@0 1103 "odd-row-color", &colorValuePtr,
michael@0 1104 nullptr);
michael@0 1105
michael@0 1106 if (colorValuePtr) {
michael@0 1107 colorValue = *colorValuePtr;
michael@0 1108 } else {
michael@0 1109 gtk_widget_style_get(treeView,
michael@0 1110 "even-row-color", &colorValuePtr,
michael@0 1111 nullptr);
michael@0 1112 if (colorValuePtr)
michael@0 1113 darken_gdk_color(colorValuePtr, &colorValue);
michael@0 1114 else
michael@0 1115 darken_gdk_color(&treeView->style->base[GTK_STATE_NORMAL], &colorValue);
michael@0 1116 }
michael@0 1117
michael@0 1118 sOddCellBackground = GDK_COLOR_TO_NS_RGB(colorValue);
michael@0 1119 if (colorValuePtr)
michael@0 1120 gdk_color_free(colorValuePtr);
michael@0 1121
michael@0 1122 style = gtk_widget_get_style(button);
michael@0 1123 if (style) {
michael@0 1124 sButtonBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
michael@0 1125 sButtonOuterLightBorder =
michael@0 1126 GDK_COLOR_TO_NS_RGB(style->light[GTK_STATE_NORMAL]);
michael@0 1127 sButtonInnerDarkBorder =
michael@0 1128 GDK_COLOR_TO_NS_RGB(style->dark[GTK_STATE_NORMAL]);
michael@0 1129 }
michael@0 1130 #else
michael@0 1131 // Button text, background, border
michael@0 1132 style = gtk_widget_get_style_context(label);
michael@0 1133 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 1134 sButtonText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1135 gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
michael@0 1136 sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1137
michael@0 1138 // Combobox label and background colors
michael@0 1139 style = gtk_widget_get_style_context(comboboxLabel);
michael@0 1140 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 1141 sComboBoxText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1142
michael@0 1143 style = gtk_widget_get_style_context(combobox);
michael@0 1144 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 1145 sComboBoxBackground = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1146
michael@0 1147 // Menubar text and hover text colors
michael@0 1148 style = gtk_widget_get_style_context(menuBar);
michael@0 1149 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 1150 sMenuBarText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1151 gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
michael@0 1152 sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1153
michael@0 1154 // GTK's guide to fancy odd row background colors:
michael@0 1155 // 1) Check if a theme explicitly defines an odd row color
michael@0 1156 // 2) If not, check if it defines an even row color, and darken it
michael@0 1157 // slightly by a hardcoded value (gtkstyle.c)
michael@0 1158 // 3) If neither are defined, take the base background color and
michael@0 1159 // darken that by a hardcoded value
michael@0 1160 style = gtk_widget_get_style_context(treeView);
michael@0 1161
michael@0 1162 // Get odd row background color
michael@0 1163 gtk_style_context_save(style);
michael@0 1164 gtk_style_context_add_region(style, GTK_STYLE_REGION_ROW, GTK_REGION_ODD);
michael@0 1165 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 1166 sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1167 gtk_style_context_restore(style);
michael@0 1168
michael@0 1169 style = gtk_widget_get_style_context(button);
michael@0 1170 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 1171 sButtonBackground = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1172
michael@0 1173 gtk_style_context_get_border_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
michael@0 1174 sButtonInnerDarkBorder = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1175 gtk_style_context_get_border_color(style, GTK_STATE_FLAG_NORMAL, &color);
michael@0 1176 sButtonOuterLightBorder = GDK_RGBA_TO_NS_RGBA(color);
michael@0 1177 #endif
michael@0 1178 // Some themes have a unified menu bar, and support window dragging on it
michael@0 1179 gboolean supports_menubar_drag = FALSE;
michael@0 1180 GParamSpec *param_spec =
michael@0 1181 gtk_widget_class_find_style_property(GTK_WIDGET_GET_CLASS(menuBar),
michael@0 1182 "window-dragging");
michael@0 1183 if (param_spec) {
michael@0 1184 if (g_type_is_a(G_PARAM_SPEC_VALUE_TYPE(param_spec), G_TYPE_BOOLEAN)) {
michael@0 1185 gtk_widget_style_get(menuBar,
michael@0 1186 "window-dragging", &supports_menubar_drag,
michael@0 1187 nullptr);
michael@0 1188 }
michael@0 1189 }
michael@0 1190 sMenuSupportsDrag = supports_menubar_drag;
michael@0 1191
michael@0 1192 colorValuePtr = nullptr;
michael@0 1193 gtk_widget_style_get(linkButton, "link-color", &colorValuePtr, nullptr);
michael@0 1194 if (colorValuePtr) {
michael@0 1195 colorValue = *colorValuePtr; // we can't pass deref pointers to GDK_COLOR_TO_NS_RGB
michael@0 1196 sNativeHyperLinkText = GDK_COLOR_TO_NS_RGB(colorValue);
michael@0 1197 gdk_color_free(colorValuePtr);
michael@0 1198 } else {
michael@0 1199 sNativeHyperLinkText = NS_RGB(0x00,0x00,0xEE);
michael@0 1200 }
michael@0 1201
michael@0 1202 // invisible character styles
michael@0 1203 guint value;
michael@0 1204 g_object_get (entry, "invisible-char", &value, nullptr);
michael@0 1205 sInvisibleCharacter = char16_t(value);
michael@0 1206
michael@0 1207 // caret styles
michael@0 1208 gtk_widget_style_get(entry,
michael@0 1209 "cursor-aspect-ratio", &sCaretRatio,
michael@0 1210 nullptr);
michael@0 1211
michael@0 1212 gtk_widget_destroy(window);
michael@0 1213 }
michael@0 1214
michael@0 1215 // virtual
michael@0 1216 char16_t
michael@0 1217 nsLookAndFeel::GetPasswordCharacterImpl()
michael@0 1218 {
michael@0 1219 return sInvisibleCharacter;
michael@0 1220 }
michael@0 1221
michael@0 1222 void
michael@0 1223 nsLookAndFeel::RefreshImpl()
michael@0 1224 {
michael@0 1225 nsXPLookAndFeel::RefreshImpl();
michael@0 1226
michael@0 1227 mDefaultFontCached = false;
michael@0 1228 mButtonFontCached = false;
michael@0 1229 mFieldFontCached = false;
michael@0 1230 mMenuFontCached = false;
michael@0 1231
michael@0 1232 #if (MOZ_WIDGET_GTK == 2)
michael@0 1233 g_object_unref(mStyle);
michael@0 1234 mStyle = nullptr;
michael@0 1235 #else
michael@0 1236 g_object_unref(mBackgroundStyle);
michael@0 1237 g_object_unref(mViewStyle);
michael@0 1238 g_object_unref(mButtonStyle);
michael@0 1239
michael@0 1240 mBackgroundStyle = nullptr;
michael@0 1241 mViewStyle = nullptr;
michael@0 1242 mButtonStyle = nullptr;
michael@0 1243 #endif
michael@0 1244
michael@0 1245 Init();
michael@0 1246 }
michael@0 1247
michael@0 1248 bool
michael@0 1249 nsLookAndFeel::GetEchoPasswordImpl() {
michael@0 1250 return false;
michael@0 1251 }

mercurial