2005-08-20 11:11:46 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2005-08-20 11:11:46 +04:00
|
|
|
|
|
|
|
#include "nsNativeThemeGTK.h"
|
|
|
|
#include "nsThemeConstants.h"
|
|
|
|
#include "gtkdrawing.h"
|
2017-03-09 14:29:44 +03:00
|
|
|
#include "ScreenHelperGTK.h"
|
2005-08-20 11:11:46 +04:00
|
|
|
|
2015-04-21 18:04:57 +03:00
|
|
|
#include "gfx2DGlue.h"
|
2005-08-20 11:13:34 +04:00
|
|
|
#include "nsIObserverService.h"
|
|
|
|
#include "nsIServiceManager.h"
|
2005-08-20 11:11:46 +04:00
|
|
|
#include "nsIFrame.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsIContent.h"
|
2013-01-05 07:12:24 +04:00
|
|
|
#include "nsViewManager.h"
|
2014-02-28 03:04:46 +04:00
|
|
|
#include "nsNameSpaceManager.h"
|
2005-08-23 06:11:54 +04:00
|
|
|
#include "nsGfxCIID.h"
|
2005-08-20 11:11:46 +04:00
|
|
|
#include "nsTransform2D.h"
|
2011-07-11 18:05:07 +04:00
|
|
|
#include "nsMenuFrame.h"
|
2005-08-20 11:13:04 +04:00
|
|
|
#include "prlink.h"
|
2011-10-14 22:11:22 +04:00
|
|
|
#include "nsGkAtoms.h"
|
2016-04-21 02:49:09 +03:00
|
|
|
#include "nsAttrValueInlines.h"
|
2014-04-03 08:18:36 +04:00
|
|
|
|
2018-02-21 01:10:44 +03:00
|
|
|
#include "mozilla/dom/HTMLInputElement.h"
|
2014-04-03 08:18:36 +04:00
|
|
|
#include "mozilla/EventStates.h"
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 20:59:13 +04:00
|
|
|
#include "mozilla/Services.h"
|
2005-08-20 11:11:46 +04:00
|
|
|
|
|
|
|
#include <gdk/gdkprivate.h>
|
2007-11-13 11:43:03 +03:00
|
|
|
#include <gtk/gtk.h>
|
2018-01-12 13:07:23 +03:00
|
|
|
#include <gtk/gtkx.h>
|
2005-08-20 11:13:14 +04:00
|
|
|
|
2005-10-06 08:02:10 +04:00
|
|
|
#include "gfxContext.h"
|
2005-11-29 23:12:29 +03:00
|
|
|
#include "gfxPlatformGtk.h"
|
2008-08-07 00:48:55 +04:00
|
|
|
#include "gfxGdkNativeRenderer.h"
|
2015-05-01 21:08:04 +03:00
|
|
|
#include "mozilla/gfx/BorrowedContext.h"
|
|
|
|
#include "mozilla/gfx/HelpersCairo.h"
|
2015-06-09 20:46:09 +03:00
|
|
|
#include "mozilla/gfx/PathHelpers.h"
|
2018-01-18 13:52:59 +03:00
|
|
|
#include "mozilla/Preferences.h"
|
2015-05-01 21:08:04 +03:00
|
|
|
|
|
|
|
#ifdef MOZ_X11
|
|
|
|
# ifdef CAIRO_HAS_XLIB_SURFACE
|
|
|
|
# include "cairo-xlib.h"
|
|
|
|
# endif
|
|
|
|
# ifdef CAIRO_HAS_XLIB_XRENDER_SURFACE
|
|
|
|
# include "cairo-xlib-xrender.h"
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2013-01-15 16:22:03 +04:00
|
|
|
#include <algorithm>
|
2015-03-29 19:06:00 +03:00
|
|
|
#include <dlfcn.h>
|
2005-10-06 08:02:10 +04:00
|
|
|
|
2014-04-03 08:18:36 +04:00
|
|
|
using namespace mozilla;
|
2014-10-25 12:08:00 +04:00
|
|
|
using namespace mozilla::gfx;
|
2018-01-12 14:40:14 +03:00
|
|
|
using namespace mozilla::widget;
|
2018-02-21 01:10:44 +03:00
|
|
|
using mozilla::dom::HTMLInputElement;
|
2014-04-03 08:18:36 +04:00
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS_INHERITED(nsNativeThemeGTK, nsNativeTheme, nsITheme,
|
|
|
|
nsIObserver)
|
2005-08-20 11:11:46 +04:00
|
|
|
|
2008-08-07 00:48:55 +04:00
|
|
|
static int gLastGdkError;
|
2005-08-20 11:12:59 +04:00
|
|
|
|
2018-01-18 13:52:59 +03:00
|
|
|
// Return scale factor of the monitor where the window is located
|
|
|
|
// by the most part or layout.css.devPixelsPerPx pref if set to > 0.
|
|
|
|
static inline gint
|
|
|
|
GetMonitorScaleFactor(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
// When the layout.css.devPixelsPerPx is set the scale can be < 1,
|
|
|
|
// the real monitor scale cannot go under 1.
|
|
|
|
double scale = nsIWidget::DefaultScaleOverride();
|
|
|
|
if (scale <= 0) {
|
|
|
|
nsIWidget* rootWidget = aFrame->PresContext()->GetRootWidget();
|
|
|
|
if (rootWidget) {
|
|
|
|
// We need to use GetDefaultScale() despite it returns monitor scale
|
|
|
|
// factor multiplied by font scale factor because it is the only scale
|
|
|
|
// updated in nsPuppetWidget.
|
|
|
|
// Since we don't want to apply font scale factor for UI elements
|
|
|
|
// (because GTK does not do so) we need to remove that from returned value.
|
|
|
|
return rootWidget->GetDefaultScale().scale / gfxPlatformGtk::GetFontScaleFactor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// We cannot return zero scale because that would lead to divide by zero
|
|
|
|
return (scale < 1) ? 1 : int(round(scale));
|
|
|
|
}
|
|
|
|
|
2005-08-20 11:11:46 +04:00
|
|
|
nsNativeThemeGTK::nsNativeThemeGTK()
|
|
|
|
{
|
2005-08-20 11:13:04 +04:00
|
|
|
if (moz_gtk_init() != MOZ_GTK_SUCCESS) {
|
|
|
|
memset(mDisabledWidgetTypes, 0xff, sizeof(mDisabledWidgetTypes));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-08-20 11:13:34 +04:00
|
|
|
// We have to call moz_gtk_shutdown before the event loop stops running.
|
|
|
|
nsCOMPtr<nsIObserverService> obsServ =
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 20:59:13 +04:00
|
|
|
mozilla::services::GetObserverService();
|
2012-03-08 05:15:57 +04:00
|
|
|
obsServ->AddObserver(this, "xpcom-shutdown", false);
|
2005-08-20 11:13:34 +04:00
|
|
|
|
2017-06-07 08:27:18 +03:00
|
|
|
ThemeChanged();
|
2005-08-20 11:11:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsNativeThemeGTK::~nsNativeThemeGTK() {
|
2005-08-20 11:13:34 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeGTK::Observe(nsISupports *aSubject, const char *aTopic,
|
2014-01-04 19:02:17 +04:00
|
|
|
const char16_t *aData)
|
2005-08-20 11:13:34 +04:00
|
|
|
{
|
2012-03-08 05:15:57 +04:00
|
|
|
if (!nsCRT::strcmp(aTopic, "xpcom-shutdown")) {
|
2005-08-20 11:13:34 +04:00
|
|
|
moz_gtk_shutdown();
|
2012-03-08 05:15:57 +04:00
|
|
|
} else {
|
|
|
|
NS_NOTREACHED("unexpected topic");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
2005-08-20 11:13:34 +04:00
|
|
|
}
|
2012-03-08 05:15:57 +04:00
|
|
|
|
|
|
|
return NS_OK;
|
2005-08-20 11:11:46 +04:00
|
|
|
}
|
|
|
|
|
2005-08-20 11:14:11 +04:00
|
|
|
void
|
|
|
|
nsNativeThemeGTK::RefreshWidgetWindow(nsIFrame* aFrame)
|
2005-08-20 11:11:46 +04:00
|
|
|
{
|
2005-08-20 11:14:11 +04:00
|
|
|
nsIPresShell *shell = GetPresShell(aFrame);
|
2005-08-20 11:12:57 +04:00
|
|
|
if (!shell)
|
|
|
|
return;
|
|
|
|
|
2013-01-05 07:12:24 +04:00
|
|
|
nsViewManager* vm = shell->GetViewManager();
|
2005-08-20 11:12:57 +04:00
|
|
|
if (!vm)
|
|
|
|
return;
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2011-12-24 07:52:25 +04:00
|
|
|
vm->InvalidateAllViews();
|
2005-08-20 11:12:57 +04:00
|
|
|
}
|
|
|
|
|
2015-03-29 19:06:00 +03:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
static bool IsFrameContentNodeInNamespace(nsIFrame *aFrame, uint32_t aNamespace)
|
2009-06-02 07:58:06 +04:00
|
|
|
{
|
2012-07-30 18:20:58 +04:00
|
|
|
nsIContent *content = aFrame ? aFrame->GetContent() : nullptr;
|
2009-06-02 07:58:06 +04:00
|
|
|
if (!content)
|
|
|
|
return false;
|
2009-08-25 00:02:07 +04:00
|
|
|
return content->IsInNamespace(aNamespace);
|
2009-06-02 07:58:06 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
static bool IsWidgetTypeDisabled(uint8_t* aDisabledVector, uint8_t aWidgetType) {
|
2017-06-07 08:27:18 +03:00
|
|
|
MOZ_ASSERT(aWidgetType < ThemeWidgetType_COUNT);
|
2008-09-16 04:00:09 +04:00
|
|
|
return (aDisabledVector[aWidgetType >> 3] & (1 << (aWidgetType & 7))) != 0;
|
2005-08-20 11:12:57 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
static void SetWidgetTypeDisabled(uint8_t* aDisabledVector, uint8_t aWidgetType) {
|
2017-06-07 08:27:18 +03:00
|
|
|
MOZ_ASSERT(aWidgetType < ThemeWidgetType_COUNT);
|
2005-08-20 11:12:57 +04:00
|
|
|
aDisabledVector[aWidgetType >> 3] |= (1 << (aWidgetType & 7));
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
static inline uint16_t
|
|
|
|
GetWidgetStateKey(uint8_t aWidgetType, GtkWidgetState *aWidgetState)
|
2005-08-20 11:13:43 +04:00
|
|
|
{
|
|
|
|
return (aWidgetState->active |
|
|
|
|
aWidgetState->focused << 1 |
|
|
|
|
aWidgetState->inHover << 2 |
|
|
|
|
aWidgetState->disabled << 3 |
|
|
|
|
aWidgetState->isDefault << 4 |
|
|
|
|
aWidgetType << 5);
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
static bool IsWidgetStateSafe(uint8_t* aSafeVector,
|
|
|
|
uint8_t aWidgetType,
|
2005-08-20 11:13:43 +04:00
|
|
|
GtkWidgetState *aWidgetState)
|
|
|
|
{
|
2017-06-07 08:27:18 +03:00
|
|
|
MOZ_ASSERT(aWidgetType < ThemeWidgetType_COUNT);
|
2017-06-07 08:27:18 +03:00
|
|
|
uint16_t key = GetWidgetStateKey(aWidgetType, aWidgetState);
|
2008-09-16 04:00:09 +04:00
|
|
|
return (aSafeVector[key >> 3] & (1 << (key & 7))) != 0;
|
2005-08-20 11:13:43 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
static void SetWidgetStateSafe(uint8_t *aSafeVector,
|
|
|
|
uint8_t aWidgetType,
|
2005-08-20 11:13:43 +04:00
|
|
|
GtkWidgetState *aWidgetState)
|
|
|
|
{
|
2017-06-07 08:27:18 +03:00
|
|
|
MOZ_ASSERT(aWidgetType < ThemeWidgetType_COUNT);
|
2017-06-07 08:27:18 +03:00
|
|
|
uint16_t key = GetWidgetStateKey(aWidgetType, aWidgetState);
|
2005-08-20 11:13:43 +04:00
|
|
|
aSafeVector[key >> 3] |= (1 << (key & 7));
|
|
|
|
}
|
|
|
|
|
2016-10-20 07:57:55 +03:00
|
|
|
/* static */ GtkTextDirection
|
|
|
|
nsNativeThemeGTK::GetTextDirection(nsIFrame* aFrame)
|
2007-12-14 10:26:03 +03:00
|
|
|
{
|
2016-10-20 07:57:55 +03:00
|
|
|
// IsFrameRTL() treats vertical-rl modes as right-to-left (in addition to
|
|
|
|
// horizontal text with direction=RTL), rather than just considering the
|
|
|
|
// text direction. GtkTextDirection does not have distinct values for
|
|
|
|
// vertical writing modes, but considering the block flow direction is
|
|
|
|
// important for resizers and scrollbar elements, at least.
|
|
|
|
return IsFrameRTL(aFrame) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
|
2007-12-14 10:26:03 +03:00
|
|
|
}
|
|
|
|
|
2010-07-15 02:31:41 +04:00
|
|
|
// Returns positive for negative margins (otherwise 0).
|
|
|
|
gint
|
|
|
|
nsNativeThemeGTK::GetTabMarginPixels(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
nscoord margin =
|
|
|
|
IsBottomTab(aFrame) ? aFrame->GetUsedMargin().top
|
|
|
|
: aFrame->GetUsedMargin().bottom;
|
|
|
|
|
2013-01-15 16:22:03 +04:00
|
|
|
return std::min<gint>(MOZ_GTK_TAB_MARGIN_MASK,
|
|
|
|
std::max(0,
|
2010-07-15 02:31:41 +04:00
|
|
|
aFrame->PresContext()->AppUnitsToDevPixels(-margin)));
|
|
|
|
}
|
|
|
|
|
2016-04-21 02:49:09 +03:00
|
|
|
static bool ShouldScrollbarButtonBeDisabled(int32_t aCurpos, int32_t aMaxpos,
|
|
|
|
uint8_t aWidgetType)
|
|
|
|
{
|
2016-05-18 20:29:56 +03:00
|
|
|
return ((aCurpos == 0 && (aWidgetType == NS_THEME_SCROLLBARBUTTON_UP ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT))
|
|
|
|
|| (aCurpos == aMaxpos && (aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT)));
|
2016-04-21 02:49:09 +03:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2012-08-22 19:56:38 +04:00
|
|
|
nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame,
|
2016-04-14 08:47:20 +03:00
|
|
|
WidgetNodeType& aGtkWidgetType,
|
2005-08-20 11:13:04 +04:00
|
|
|
GtkWidgetState* aState,
|
|
|
|
gint* aWidgetFlags)
|
2005-08-20 11:11:46 +04:00
|
|
|
{
|
2005-08-20 11:13:04 +04:00
|
|
|
if (aState) {
|
2016-05-23 11:04:51 +03:00
|
|
|
// For XUL checkboxes and radio buttons, the state of the parent
|
|
|
|
// determines our state.
|
|
|
|
nsIFrame *stateFrame = aFrame;
|
|
|
|
if (aFrame && ((aWidgetFlags && (aWidgetType == NS_THEME_CHECKBOX ||
|
|
|
|
aWidgetType == NS_THEME_RADIO)) ||
|
|
|
|
aWidgetType == NS_THEME_CHECKBOX_LABEL ||
|
|
|
|
aWidgetType == NS_THEME_RADIO_LABEL)) {
|
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
nsAtom* atom = nullptr;
|
2016-05-23 11:04:51 +03:00
|
|
|
if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) {
|
|
|
|
if (aWidgetType == NS_THEME_CHECKBOX_LABEL ||
|
|
|
|
aWidgetType == NS_THEME_RADIO_LABEL) {
|
|
|
|
// Adjust stateFrame so GetContentState finds the correct state.
|
|
|
|
stateFrame = aFrame = aFrame->GetParent()->GetParent();
|
2006-02-23 04:01:29 +03:00
|
|
|
} else {
|
2016-05-23 11:04:51 +03:00
|
|
|
// GetContentState knows to look one frame up for radio/checkbox
|
|
|
|
// widgets, so don't adjust stateFrame here.
|
|
|
|
aFrame = aFrame->GetParent();
|
|
|
|
}
|
|
|
|
if (aWidgetFlags) {
|
|
|
|
if (!atom) {
|
|
|
|
atom = (aWidgetType == NS_THEME_CHECKBOX ||
|
|
|
|
aWidgetType == NS_THEME_CHECKBOX_LABEL) ? nsGkAtoms::checked
|
|
|
|
: nsGkAtoms::selected;
|
|
|
|
}
|
|
|
|
*aWidgetFlags = CheckBooleanAttr(aFrame, atom);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (aWidgetFlags) {
|
|
|
|
*aWidgetFlags = 0;
|
2018-02-21 01:10:44 +03:00
|
|
|
HTMLInputElement* inputElt = HTMLInputElement::FromContent(aFrame->GetContent());
|
|
|
|
if (inputElt && inputElt->Checked())
|
|
|
|
*aWidgetFlags |= MOZ_GTK_WIDGET_CHECKED;
|
2016-05-23 11:04:51 +03:00
|
|
|
|
|
|
|
if (GetIndeterminate(aFrame))
|
|
|
|
*aWidgetFlags |= MOZ_GTK_WIDGET_INCONSISTENT;
|
2005-08-20 11:13:51 +04:00
|
|
|
}
|
|
|
|
}
|
2016-05-23 11:04:51 +03:00
|
|
|
} else if (aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN ||
|
|
|
|
aWidgetType == NS_THEME_TREEHEADERSORTARROW ||
|
|
|
|
aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS ||
|
|
|
|
aWidgetType == NS_THEME_BUTTON_ARROW_NEXT ||
|
|
|
|
aWidgetType == NS_THEME_BUTTON_ARROW_UP ||
|
|
|
|
aWidgetType == NS_THEME_BUTTON_ARROW_DOWN) {
|
|
|
|
// The state of an arrow comes from its parent.
|
|
|
|
stateFrame = aFrame = aFrame->GetParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
EventStates eventState = GetContentState(stateFrame, aWidgetType);
|
|
|
|
|
|
|
|
aState->disabled = IsDisabled(aFrame, eventState) || IsReadOnly(aFrame);
|
|
|
|
aState->active = eventState.HasState(NS_EVENT_STATE_ACTIVE);
|
|
|
|
aState->focused = eventState.HasState(NS_EVENT_STATE_FOCUS);
|
|
|
|
aState->inHover = eventState.HasState(NS_EVENT_STATE_HOVER);
|
|
|
|
aState->isDefault = IsDefaultButton(aFrame);
|
|
|
|
aState->canDefault = FALSE; // XXX fix me
|
|
|
|
aState->depressed = FALSE;
|
|
|
|
|
|
|
|
if (aWidgetType == NS_THEME_FOCUS_OUTLINE) {
|
|
|
|
aState->disabled = FALSE;
|
|
|
|
aState->active = FALSE;
|
|
|
|
aState->inHover = FALSE;
|
|
|
|
aState->isDefault = FALSE;
|
|
|
|
aState->canDefault = FALSE;
|
|
|
|
|
|
|
|
aState->focused = TRUE;
|
|
|
|
aState->depressed = TRUE; // see moz_gtk_entry_paint()
|
|
|
|
} else if (aWidgetType == NS_THEME_BUTTON ||
|
|
|
|
aWidgetType == NS_THEME_TOOLBARBUTTON ||
|
|
|
|
aWidgetType == NS_THEME_DUALBUTTON ||
|
|
|
|
aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN ||
|
|
|
|
aWidgetType == NS_THEME_MENULIST ||
|
|
|
|
aWidgetType == NS_THEME_MENULIST_BUTTON) {
|
|
|
|
aState->active &= aState->inHover;
|
|
|
|
}
|
2005-08-20 11:13:14 +04:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) {
|
|
|
|
// For these widget types, some element (either a child or parent)
|
|
|
|
// actually has element focus, so we check the focused attribute
|
|
|
|
// to see whether to draw in the focused state.
|
|
|
|
if (aWidgetType == NS_THEME_NUMBER_INPUT ||
|
|
|
|
aWidgetType == NS_THEME_TEXTFIELD ||
|
|
|
|
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
|
|
|
|
aWidgetType == NS_THEME_MENULIST_TEXTFIELD ||
|
|
|
|
aWidgetType == NS_THEME_SPINNER_TEXTFIELD ||
|
|
|
|
aWidgetType == NS_THEME_RADIO_CONTAINER ||
|
|
|
|
aWidgetType == NS_THEME_RADIO_LABEL) {
|
|
|
|
aState->focused = IsFocused(aFrame);
|
|
|
|
} else if (aWidgetType == NS_THEME_RADIO ||
|
|
|
|
aWidgetType == NS_THEME_CHECKBOX) {
|
|
|
|
// In XUL, checkboxes and radios shouldn't have focus rings, their labels do
|
|
|
|
aState->focused = FALSE;
|
2014-06-14 16:48:08 +04:00
|
|
|
}
|
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
if (aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL) {
|
|
|
|
// for scrollbars we need to go up two to go from the thumb to
|
|
|
|
// the slider to the actual scrollbar object
|
|
|
|
nsIFrame *tmpFrame = aFrame->GetParent()->GetParent();
|
2005-08-20 11:13:50 +04:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
aState->curpos = CheckIntAttr(tmpFrame, nsGkAtoms::curpos, 0);
|
|
|
|
aState->maxpos = CheckIntAttr(tmpFrame, nsGkAtoms::maxpos, 100);
|
2007-06-26 08:13:30 +04:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
if (CheckBooleanAttr(aFrame, nsGkAtoms::active)) {
|
|
|
|
aState->active = TRUE;
|
|
|
|
// Set hover state to emulate Gtk style of active scrollbar thumb
|
|
|
|
aState->inHover = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2014-08-13 14:02:00 +04:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
if (aWidgetType == NS_THEME_SCROLLBARBUTTON_UP ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT) {
|
|
|
|
// set the state to disabled when the scrollbar is scrolled to
|
|
|
|
// the beginning or the end, depending on the button type.
|
|
|
|
int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0);
|
|
|
|
int32_t maxpos = CheckIntAttr(aFrame, nsGkAtoms::maxpos, 100);
|
|
|
|
if (ShouldScrollbarButtonBeDisabled(curpos, maxpos, aWidgetType)) {
|
|
|
|
aState->disabled = true;
|
2007-06-27 02:16:07 +04:00
|
|
|
}
|
2007-06-26 08:13:30 +04:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
// In order to simulate native GTK scrollbar click behavior,
|
|
|
|
// we set the active attribute on the element to true if it's
|
|
|
|
// pressed with any mouse button.
|
|
|
|
// This allows us to show that it's active without setting :active
|
|
|
|
else if (CheckBooleanAttr(aFrame, nsGkAtoms::active))
|
|
|
|
aState->active = true;
|
|
|
|
|
|
|
|
if (aWidgetFlags) {
|
|
|
|
*aWidgetFlags = GetScrollbarButtonType(aFrame);
|
|
|
|
if (aWidgetType - NS_THEME_SCROLLBARBUTTON_UP < 2)
|
|
|
|
*aWidgetFlags |= MOZ_GTK_STEPPER_VERTICAL;
|
|
|
|
}
|
|
|
|
}
|
2008-02-07 12:26:22 +03:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
// menu item state is determined by the attribute "_moz-menuactive",
|
|
|
|
// and not by the mouse hovering (accessibility). as a special case,
|
|
|
|
// menus which are children of a menu bar are only marked as prelight
|
|
|
|
// if they are open, not on normal hover.
|
|
|
|
|
|
|
|
if (aWidgetType == NS_THEME_MENUITEM ||
|
|
|
|
aWidgetType == NS_THEME_CHECKMENUITEM ||
|
|
|
|
aWidgetType == NS_THEME_RADIOMENUITEM ||
|
|
|
|
aWidgetType == NS_THEME_MENUSEPARATOR ||
|
|
|
|
aWidgetType == NS_THEME_MENUARROW) {
|
|
|
|
bool isTopLevel = false;
|
|
|
|
nsMenuFrame *menuFrame = do_QueryFrame(aFrame);
|
|
|
|
if (menuFrame) {
|
|
|
|
isTopLevel = menuFrame->IsOnMenuBar();
|
2007-06-27 02:16:07 +04:00
|
|
|
}
|
2007-06-26 08:13:30 +04:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
if (isTopLevel) {
|
|
|
|
aState->inHover = menuFrame->IsOpen();
|
|
|
|
} else {
|
|
|
|
aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
|
|
|
|
}
|
2007-06-27 10:38:51 +04:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
aState->active = FALSE;
|
2007-06-27 10:38:51 +04:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
if (aWidgetType == NS_THEME_CHECKMENUITEM ||
|
|
|
|
aWidgetType == NS_THEME_RADIOMENUITEM) {
|
|
|
|
*aWidgetFlags = 0;
|
2017-12-07 21:13:50 +03:00
|
|
|
if (aFrame && aFrame->GetContent() &&
|
|
|
|
aFrame->GetContent()->IsElement()) {
|
|
|
|
*aWidgetFlags = aFrame->GetContent()->AsElement()->
|
2016-05-23 11:04:51 +03:00
|
|
|
AttrValueIs(kNameSpaceID_None, nsGkAtoms::checked,
|
|
|
|
nsGkAtoms::_true, eIgnoreCase);
|
2007-06-27 10:38:51 +04:00
|
|
|
}
|
2005-08-20 11:14:21 +04:00
|
|
|
}
|
2016-05-23 11:04:51 +03:00
|
|
|
}
|
2007-12-03 12:14:18 +03:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
// A button with drop down menu open or an activated toggle button
|
|
|
|
// should always appear depressed.
|
|
|
|
if (aWidgetType == NS_THEME_BUTTON ||
|
|
|
|
aWidgetType == NS_THEME_TOOLBARBUTTON ||
|
|
|
|
aWidgetType == NS_THEME_DUALBUTTON ||
|
|
|
|
aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN ||
|
|
|
|
aWidgetType == NS_THEME_MENULIST ||
|
|
|
|
aWidgetType == NS_THEME_MENULIST_BUTTON) {
|
|
|
|
bool menuOpen = IsOpenButton(aFrame);
|
|
|
|
aState->depressed = IsCheckedButton(aFrame) || menuOpen;
|
|
|
|
// we must not highlight buttons with open drop down menus on hover.
|
|
|
|
aState->inHover = aState->inHover && !menuOpen;
|
|
|
|
}
|
2008-02-10 11:30:04 +03:00
|
|
|
|
2016-05-23 11:04:51 +03:00
|
|
|
// When the input field of the drop down button has focus, some themes
|
|
|
|
// should draw focus for the drop down button as well.
|
|
|
|
if (aWidgetType == NS_THEME_MENULIST_BUTTON && aWidgetFlags) {
|
|
|
|
*aWidgetFlags = CheckBooleanAttr(aFrame, nsGkAtoms::parentfocused);
|
2005-08-20 11:13:48 +04:00
|
|
|
}
|
2005-08-20 11:13:04 +04:00
|
|
|
}
|
2005-08-20 11:11:46 +04:00
|
|
|
}
|
2005-08-20 11:12:57 +04:00
|
|
|
|
2005-08-20 11:11:46 +04:00
|
|
|
switch (aWidgetType) {
|
2005-08-20 11:11:47 +04:00
|
|
|
case NS_THEME_BUTTON:
|
2015-08-07 08:09:00 +03:00
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_RELIEF_NORMAL;
|
|
|
|
aGtkWidgetType = MOZ_GTK_BUTTON;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TOOLBARBUTTON:
|
|
|
|
case NS_THEME_DUALBUTTON:
|
2005-08-20 11:13:04 +04:00
|
|
|
if (aWidgetFlags)
|
2015-08-07 08:09:00 +03:00
|
|
|
*aWidgetFlags = GTK_RELIEF_NONE;
|
|
|
|
aGtkWidgetType = MOZ_GTK_TOOLBAR_BUTTON;
|
2005-08-20 11:11:46 +04:00
|
|
|
break;
|
2014-06-14 16:48:08 +04:00
|
|
|
case NS_THEME_FOCUS_OUTLINE:
|
|
|
|
aGtkWidgetType = MOZ_GTK_ENTRY;
|
|
|
|
break;
|
2005-08-20 11:11:46 +04:00
|
|
|
case NS_THEME_CHECKBOX:
|
2005-08-20 11:12:15 +04:00
|
|
|
case NS_THEME_RADIO:
|
2008-11-03 16:12:59 +03:00
|
|
|
aGtkWidgetType = (aWidgetType == NS_THEME_RADIO) ? MOZ_GTK_RADIOBUTTON : MOZ_GTK_CHECKBUTTON;
|
2005-08-20 11:13:04 +04:00
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCROLLBARBUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBARBUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBARBUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBARBUTTON_RIGHT:
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_SCROLLBAR_BUTTON;
|
2005-08-20 11:11:47 +04:00
|
|
|
break;
|
2015-12-22 07:05:00 +03:00
|
|
|
case NS_THEME_SCROLLBAR_VERTICAL:
|
|
|
|
aGtkWidgetType = MOZ_GTK_SCROLLBAR_VERTICAL;
|
2015-07-14 14:35:00 +03:00
|
|
|
if (GetWidgetTransparency(aFrame, aWidgetType) == eOpaque)
|
|
|
|
*aWidgetFlags = MOZ_GTK_TRACK_OPAQUE;
|
|
|
|
else
|
|
|
|
*aWidgetFlags = 0;
|
2005-08-20 11:13:14 +04:00
|
|
|
break;
|
2015-12-22 07:05:00 +03:00
|
|
|
case NS_THEME_SCROLLBAR_HORIZONTAL:
|
|
|
|
aGtkWidgetType = MOZ_GTK_SCROLLBAR_HORIZONTAL;
|
2015-07-14 14:35:00 +03:00
|
|
|
if (GetWidgetTransparency(aFrame, aWidgetType) == eOpaque)
|
|
|
|
*aWidgetFlags = MOZ_GTK_TRACK_OPAQUE;
|
|
|
|
else
|
|
|
|
*aWidgetFlags = 0;
|
2005-08-20 11:12:11 +04:00
|
|
|
break;
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
case NS_THEME_SCROLLBARTRACK_HORIZONTAL:
|
2017-01-09 09:33:27 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL;
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
break;
|
|
|
|
case NS_THEME_SCROLLBARTRACK_VERTICAL:
|
2017-01-09 09:33:27 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL;
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCROLLBARTHUMB_VERTICAL:
|
2005-08-20 11:13:14 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_SCROLLBAR_THUMB_VERTICAL;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCROLLBARTHUMB_HORIZONTAL:
|
2005-08-20 11:13:14 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
|
2005-08-20 11:12:11 +04:00
|
|
|
break;
|
2017-11-29 05:43:13 +03:00
|
|
|
case NS_THEME_INNER_SPIN_BUTTON:
|
|
|
|
aGtkWidgetType = MOZ_GTK_INNER_SPIN_BUTTON;
|
|
|
|
break;
|
2007-12-21 14:30:29 +03:00
|
|
|
case NS_THEME_SPINNER:
|
|
|
|
aGtkWidgetType = MOZ_GTK_SPINBUTTON;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SPINNER_UPBUTTON:
|
2006-07-13 21:40:49 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_SPINBUTTON_UP;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SPINNER_DOWNBUTTON:
|
2006-07-13 21:40:49 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_SPINBUTTON_DOWN;
|
|
|
|
break;
|
2007-12-21 14:30:29 +03:00
|
|
|
case NS_THEME_SPINNER_TEXTFIELD:
|
|
|
|
aGtkWidgetType = MOZ_GTK_SPINBUTTON_ENTRY;
|
|
|
|
break;
|
2013-03-29 00:25:05 +04:00
|
|
|
case NS_THEME_RANGE:
|
|
|
|
{
|
|
|
|
if (IsRangeHorizontal(aFrame)) {
|
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_ORIENTATION_HORIZONTAL;
|
|
|
|
aGtkWidgetType = MOZ_GTK_SCALE_HORIZONTAL;
|
|
|
|
} else {
|
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_ORIENTATION_VERTICAL;
|
|
|
|
aGtkWidgetType = MOZ_GTK_SCALE_VERTICAL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NS_THEME_RANGE_THUMB:
|
|
|
|
{
|
|
|
|
if (IsRangeHorizontal(aFrame)) {
|
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_ORIENTATION_HORIZONTAL;
|
|
|
|
aGtkWidgetType = MOZ_GTK_SCALE_THUMB_HORIZONTAL;
|
|
|
|
} else {
|
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_ORIENTATION_VERTICAL;
|
|
|
|
aGtkWidgetType = MOZ_GTK_SCALE_THUMB_VERTICAL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2006-05-30 17:50:48 +04:00
|
|
|
case NS_THEME_SCALE_HORIZONTAL:
|
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_ORIENTATION_HORIZONTAL;
|
|
|
|
aGtkWidgetType = MOZ_GTK_SCALE_HORIZONTAL;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCALETHUMB_HORIZONTAL:
|
2006-05-30 17:50:48 +04:00
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_ORIENTATION_HORIZONTAL;
|
|
|
|
aGtkWidgetType = MOZ_GTK_SCALE_THUMB_HORIZONTAL;
|
|
|
|
break;
|
|
|
|
case NS_THEME_SCALE_VERTICAL:
|
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_ORIENTATION_VERTICAL;
|
|
|
|
aGtkWidgetType = MOZ_GTK_SCALE_VERTICAL;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SEPARATOR:
|
2007-12-03 12:13:29 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_TOOLBAR_SEPARATOR;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCALETHUMB_VERTICAL:
|
2006-05-30 17:50:48 +04:00
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_ORIENTATION_VERTICAL;
|
|
|
|
aGtkWidgetType = MOZ_GTK_SCALE_THUMB_VERTICAL;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TOOLBARGRIPPER:
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_GRIPPER;
|
2005-08-20 11:12:11 +04:00
|
|
|
break;
|
2007-11-09 10:32:54 +03:00
|
|
|
case NS_THEME_RESIZER:
|
|
|
|
aGtkWidgetType = MOZ_GTK_RESIZER;
|
|
|
|
break;
|
2013-12-09 03:23:28 +04:00
|
|
|
case NS_THEME_NUMBER_INPUT:
|
2005-08-20 11:12:17 +04:00
|
|
|
case NS_THEME_TEXTFIELD:
|
2016-04-27 02:07:00 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_ENTRY;
|
|
|
|
break;
|
2007-05-07 06:06:58 +04:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2018-01-09 13:51:07 +03:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
2016-04-27 02:07:00 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_TEXT_VIEW;
|
|
|
|
#else
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_ENTRY;
|
2016-04-27 02:07:00 +03:00
|
|
|
#endif
|
2005-08-20 11:12:17 +04:00
|
|
|
break;
|
2007-11-07 12:14:58 +03:00
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
case NS_THEME_TREEVIEW:
|
|
|
|
aGtkWidgetType = MOZ_GTK_TREEVIEW;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TREEHEADERCELL:
|
2008-03-18 22:35:23 +03:00
|
|
|
if (aWidgetFlags) {
|
|
|
|
// In this case, the flag denotes whether the header is the sorted one or not
|
|
|
|
if (GetTreeSortDirection(aFrame) == eTreeSortDirection_Natural)
|
2011-10-03 11:56:21 +04:00
|
|
|
*aWidgetFlags = false;
|
2008-03-18 22:35:23 +03:00
|
|
|
else
|
2011-10-03 11:56:21 +04:00
|
|
|
*aWidgetFlags = true;
|
2008-03-18 22:35:23 +03:00
|
|
|
}
|
2007-11-07 12:14:58 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_TREE_HEADER_CELL;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TREEHEADERSORTARROW:
|
2007-11-13 11:43:03 +03:00
|
|
|
if (aWidgetFlags) {
|
|
|
|
switch (GetTreeSortDirection(aFrame)) {
|
|
|
|
case eTreeSortDirection_Ascending:
|
|
|
|
*aWidgetFlags = GTK_ARROW_DOWN;
|
|
|
|
break;
|
|
|
|
case eTreeSortDirection_Descending:
|
|
|
|
*aWidgetFlags = GTK_ARROW_UP;
|
|
|
|
break;
|
|
|
|
case eTreeSortDirection_Natural:
|
|
|
|
default:
|
2013-05-30 16:10:02 +04:00
|
|
|
/* This prevents the treecolums from getting smaller
|
2007-11-13 11:43:03 +03:00
|
|
|
* and wider when switching sort direction off and on
|
|
|
|
* */
|
|
|
|
*aWidgetFlags = GTK_ARROW_NONE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
aGtkWidgetType = MOZ_GTK_TREE_HEADER_SORTARROW;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TREETWISTY:
|
2008-01-03 10:07:32 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_TREEVIEW_EXPANDER;
|
2007-11-15 06:47:16 +03:00
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_EXPANDER_COLLAPSED;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TREETWISTYOPEN:
|
2008-01-03 10:07:32 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_TREEVIEW_EXPANDER;
|
2007-11-15 06:47:16 +03:00
|
|
|
if (aWidgetFlags)
|
|
|
|
*aWidgetFlags = GTK_EXPANDER_EXPANDED;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_MENULIST:
|
2005-08-20 11:14:05 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_DROPDOWN;
|
2008-03-25 03:34:27 +03:00
|
|
|
if (aWidgetFlags)
|
2009-08-25 00:02:07 +04:00
|
|
|
*aWidgetFlags = IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XHTML);
|
2005-08-20 11:14:05 +04:00
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_MENULIST_TEXT:
|
2011-10-03 11:56:21 +04:00
|
|
|
return false; // nothing to do, but prevents the bg from being drawn
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_MENULIST_TEXTFIELD:
|
2008-01-14 14:12:29 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_DROPDOWN_ENTRY;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_MENULIST_BUTTON:
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_DROPDOWN_ARROW;
|
2005-08-20 11:12:17 +04:00
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TOOLBARBUTTON_DROPDOWN:
|
2010-07-27 18:57:47 +04:00
|
|
|
case NS_THEME_BUTTON_ARROW_DOWN:
|
|
|
|
case NS_THEME_BUTTON_ARROW_UP:
|
|
|
|
case NS_THEME_BUTTON_ARROW_NEXT:
|
|
|
|
case NS_THEME_BUTTON_ARROW_PREVIOUS:
|
2008-01-17 13:24:31 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_TOOLBARBUTTON_ARROW;
|
2010-07-27 18:57:47 +04:00
|
|
|
if (aWidgetFlags) {
|
|
|
|
*aWidgetFlags = GTK_ARROW_DOWN;
|
|
|
|
|
|
|
|
if (aWidgetType == NS_THEME_BUTTON_ARROW_UP)
|
|
|
|
*aWidgetFlags = GTK_ARROW_UP;
|
|
|
|
else if (aWidgetType == NS_THEME_BUTTON_ARROW_NEXT)
|
|
|
|
*aWidgetFlags = GTK_ARROW_RIGHT;
|
|
|
|
else if (aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS)
|
|
|
|
*aWidgetFlags = GTK_ARROW_LEFT;
|
|
|
|
}
|
2008-01-17 13:24:31 +03:00
|
|
|
break;
|
2005-08-20 11:12:19 +04:00
|
|
|
case NS_THEME_CHECKBOX_CONTAINER:
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_CHECKBUTTON_CONTAINER;
|
|
|
|
break;
|
2005-08-20 11:12:19 +04:00
|
|
|
case NS_THEME_RADIO_CONTAINER:
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_RADIOBUTTON_CONTAINER;
|
2005-08-20 11:12:22 +04:00
|
|
|
break;
|
2005-08-20 11:14:00 +04:00
|
|
|
case NS_THEME_CHECKBOX_LABEL:
|
|
|
|
aGtkWidgetType = MOZ_GTK_CHECKBUTTON_LABEL;
|
|
|
|
break;
|
|
|
|
case NS_THEME_RADIO_LABEL:
|
|
|
|
aGtkWidgetType = MOZ_GTK_RADIOBUTTON_LABEL;
|
|
|
|
break;
|
2005-08-20 11:13:48 +04:00
|
|
|
case NS_THEME_TOOLBAR:
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_TOOLBAR;
|
2005-08-20 11:12:19 +04:00
|
|
|
break;
|
2005-08-20 11:12:27 +04:00
|
|
|
case NS_THEME_TOOLTIP:
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_TOOLTIP;
|
2005-08-20 11:12:27 +04:00
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_STATUSBARPANEL:
|
2016-05-19 11:58:00 +03:00
|
|
|
case NS_THEME_RESIZERPANEL:
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_FRAME;
|
2005-08-20 11:12:28 +04:00
|
|
|
break;
|
2005-08-20 11:12:29 +04:00
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_PROGRESSBAR;
|
2005-08-20 11:12:29 +04:00
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_PROGRESSCHUNK:
|
|
|
|
case NS_THEME_PROGRESSCHUNK_VERTICAL:
|
2011-05-05 17:11:35 +04:00
|
|
|
{
|
|
|
|
nsIFrame* stateFrame = aFrame->GetParent();
|
2014-04-03 08:18:36 +04:00
|
|
|
EventStates eventStates = GetContentState(stateFrame, aWidgetType);
|
2011-05-05 17:11:35 +04:00
|
|
|
|
|
|
|
aGtkWidgetType = IsIndeterminateProgress(stateFrame, eventStates)
|
2014-06-24 22:26:13 +04:00
|
|
|
? IsVerticalProgress(stateFrame)
|
2011-05-16 14:59:10 +04:00
|
|
|
? MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE
|
|
|
|
: MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE
|
2011-05-05 17:11:35 +04:00
|
|
|
: MOZ_GTK_PROGRESS_CHUNK;
|
|
|
|
}
|
2005-08-20 11:12:29 +04:00
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TAB_SCROLL_ARROW_BACK:
|
|
|
|
case NS_THEME_TAB_SCROLL_ARROW_FORWARD:
|
2008-02-15 08:28:44 +03:00
|
|
|
if (aWidgetFlags)
|
2016-05-18 20:29:56 +03:00
|
|
|
*aWidgetFlags = aWidgetType == NS_THEME_TAB_SCROLL_ARROW_BACK ?
|
2008-02-15 08:28:44 +03:00
|
|
|
GTK_ARROW_LEFT : GTK_ARROW_RIGHT;
|
|
|
|
aGtkWidgetType = MOZ_GTK_TAB_SCROLLARROW;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TABPANELS:
|
2005-08-20 11:13:04 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_TABPANELS;
|
2005-08-20 11:12:31 +04:00
|
|
|
break;
|
2005-08-20 11:12:30 +04:00
|
|
|
case NS_THEME_TAB:
|
|
|
|
{
|
2016-08-22 06:13:00 +03:00
|
|
|
if (IsBottomTab(aFrame)) {
|
|
|
|
aGtkWidgetType = MOZ_GTK_TAB_BOTTOM;
|
|
|
|
} else {
|
|
|
|
aGtkWidgetType = MOZ_GTK_TAB_TOP;
|
|
|
|
}
|
|
|
|
|
2005-08-20 11:13:04 +04:00
|
|
|
if (aWidgetFlags) {
|
2007-12-21 14:51:48 +03:00
|
|
|
/* First bits will be used to store max(0,-bmargin) where bmargin
|
|
|
|
* is the bottom margin of the tab in pixels (resp. top margin,
|
|
|
|
* for bottom tabs). */
|
2016-08-22 06:13:00 +03:00
|
|
|
*aWidgetFlags = GetTabMarginPixels(aFrame);
|
2005-08-20 11:12:32 +04:00
|
|
|
|
2007-12-21 14:51:48 +03:00
|
|
|
if (IsSelectedTab(aFrame))
|
2005-08-20 11:13:04 +04:00
|
|
|
*aWidgetFlags |= MOZ_GTK_TAB_SELECTED;
|
2005-08-20 11:12:32 +04:00
|
|
|
|
2007-12-21 14:51:48 +03:00
|
|
|
if (IsFirstTab(aFrame))
|
2005-08-20 11:13:33 +04:00
|
|
|
*aWidgetFlags |= MOZ_GTK_TAB_FIRST;
|
2005-08-20 11:13:04 +04:00
|
|
|
}
|
2005-08-20 11:12:30 +04:00
|
|
|
}
|
2005-08-20 11:13:04 +04:00
|
|
|
break;
|
2007-12-21 14:17:01 +03:00
|
|
|
case NS_THEME_SPLITTER:
|
|
|
|
if (IsHorizontal(aFrame))
|
|
|
|
aGtkWidgetType = MOZ_GTK_SPLITTER_VERTICAL;
|
2017-12-19 13:38:59 +03:00
|
|
|
else
|
2007-12-21 14:17:01 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_SPLITTER_HORIZONTAL;
|
|
|
|
break;
|
2005-08-20 11:13:48 +04:00
|
|
|
case NS_THEME_MENUBAR:
|
|
|
|
aGtkWidgetType = MOZ_GTK_MENUBAR;
|
|
|
|
break;
|
|
|
|
case NS_THEME_MENUPOPUP:
|
|
|
|
aGtkWidgetType = MOZ_GTK_MENUPOPUP;
|
|
|
|
break;
|
|
|
|
case NS_THEME_MENUITEM:
|
2016-05-19 07:55:04 +03:00
|
|
|
{
|
|
|
|
nsMenuFrame *menuFrame = do_QueryFrame(aFrame);
|
|
|
|
if (menuFrame && menuFrame->IsOnMenuBar()) {
|
|
|
|
aGtkWidgetType = MOZ_GTK_MENUBARITEM;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2005-08-20 11:13:48 +04:00
|
|
|
aGtkWidgetType = MOZ_GTK_MENUITEM;
|
|
|
|
break;
|
2007-12-11 12:09:09 +03:00
|
|
|
case NS_THEME_MENUSEPARATOR:
|
|
|
|
aGtkWidgetType = MOZ_GTK_MENUSEPARATOR;
|
|
|
|
break;
|
2007-11-29 01:45:21 +03:00
|
|
|
case NS_THEME_MENUARROW:
|
|
|
|
aGtkWidgetType = MOZ_GTK_MENUARROW;
|
|
|
|
break;
|
2005-08-20 11:14:21 +04:00
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
aGtkWidgetType = MOZ_GTK_CHECKMENUITEM;
|
|
|
|
break;
|
|
|
|
case NS_THEME_RADIOMENUITEM:
|
|
|
|
aGtkWidgetType = MOZ_GTK_RADIOMENUITEM;
|
|
|
|
break;
|
2005-08-20 11:13:45 +04:00
|
|
|
case NS_THEME_WINDOW:
|
|
|
|
case NS_THEME_DIALOG:
|
|
|
|
aGtkWidgetType = MOZ_GTK_WINDOW;
|
|
|
|
break;
|
2015-08-19 22:42:17 +03:00
|
|
|
case NS_THEME_GTK_INFO_BAR:
|
|
|
|
aGtkWidgetType = MOZ_GTK_INFO_BAR;
|
|
|
|
break;
|
2017-09-19 22:22:45 +03:00
|
|
|
case NS_THEME_WINDOW_TITLEBAR:
|
|
|
|
aGtkWidgetType = MOZ_GTK_HEADER_BAR;
|
|
|
|
break;
|
|
|
|
case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
|
|
|
aGtkWidgetType = MOZ_GTK_HEADER_BAR_MAXIMIZED;
|
|
|
|
break;
|
|
|
|
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
|
|
|
aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_CLOSE;
|
|
|
|
break;
|
|
|
|
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
|
|
|
aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE;
|
|
|
|
break;
|
|
|
|
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
|
|
|
aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE;
|
|
|
|
break;
|
|
|
|
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
2018-01-25 13:13:12 +03:00
|
|
|
aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_RESTORE;
|
2017-09-19 22:22:45 +03:00
|
|
|
break;
|
2005-08-20 11:13:04 +04:00
|
|
|
default:
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2005-08-20 11:11:46 +04:00
|
|
|
}
|
|
|
|
|
2011-10-03 11:56:21 +04:00
|
|
|
return true;
|
2005-08-20 11:13:04 +04:00
|
|
|
}
|
|
|
|
|
2015-06-09 20:46:09 +03:00
|
|
|
class SystemCairoClipper : public ClipExporter {
|
|
|
|
public:
|
2015-06-21 22:27:07 +03:00
|
|
|
explicit SystemCairoClipper(cairo_t* aContext) : mContext(aContext)
|
2015-06-09 20:46:09 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BeginClip(const Matrix& aTransform) override
|
|
|
|
{
|
|
|
|
cairo_matrix_t mat;
|
|
|
|
GfxMatrixToCairoMatrix(aTransform, mat);
|
|
|
|
cairo_set_matrix(mContext, &mat);
|
|
|
|
|
|
|
|
cairo_new_path(mContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MoveTo(const Point &aPoint) override
|
|
|
|
{
|
|
|
|
cairo_move_to(mContext, aPoint.x, aPoint.y);
|
|
|
|
mCurrentPoint = aPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
LineTo(const Point &aPoint) override
|
|
|
|
{
|
|
|
|
cairo_line_to(mContext, aPoint.x, aPoint.y);
|
|
|
|
mCurrentPoint = aPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BezierTo(const Point &aCP1, const Point &aCP2, const Point &aCP3) override
|
|
|
|
{
|
|
|
|
cairo_curve_to(mContext, aCP1.x, aCP1.y, aCP2.x, aCP2.y, aCP3.x, aCP3.y);
|
|
|
|
mCurrentPoint = aCP3;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
QuadraticBezierTo(const Point &aCP1, const Point &aCP2) override
|
|
|
|
{
|
|
|
|
Point CP0 = CurrentPoint();
|
|
|
|
Point CP1 = (CP0 + aCP1 * 2.0) / 3.0;
|
|
|
|
Point CP2 = (aCP2 + aCP1 * 2.0) / 3.0;
|
|
|
|
Point CP3 = aCP2;
|
|
|
|
cairo_curve_to(mContext, CP1.x, CP1.y, CP2.x, CP2.y, CP3.x, CP3.y);
|
|
|
|
mCurrentPoint = aCP2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Arc(const Point &aOrigin, float aRadius, float aStartAngle, float aEndAngle,
|
|
|
|
bool aAntiClockwise) override
|
|
|
|
{
|
|
|
|
ArcToBezier(this, aOrigin, Size(aRadius, aRadius), aStartAngle, aEndAngle,
|
|
|
|
aAntiClockwise);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Close() override
|
|
|
|
{
|
|
|
|
cairo_close_path(mContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
EndClip() override
|
|
|
|
{
|
|
|
|
cairo_clip(mContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
Point
|
|
|
|
CurrentPoint() const override
|
|
|
|
{
|
|
|
|
return mCurrentPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
cairo_t* mContext;
|
|
|
|
Point mCurrentPoint;
|
|
|
|
};
|
|
|
|
|
2015-05-01 21:08:04 +03:00
|
|
|
static void
|
|
|
|
DrawThemeWithCairo(gfxContext* aContext, DrawTarget* aDrawTarget,
|
2016-04-14 08:47:20 +03:00
|
|
|
GtkWidgetState aState, WidgetNodeType aGTKWidgetType,
|
2015-05-01 21:08:04 +03:00
|
|
|
gint aFlags, GtkTextDirection aDirection, gint aScaleFactor,
|
|
|
|
bool aSnapped, const Point& aDrawOrigin, const nsIntSize& aDrawSize,
|
|
|
|
GdkRectangle& aGDKRect, nsITheme::Transparency aTransparency)
|
|
|
|
{
|
2015-06-09 20:46:09 +03:00
|
|
|
Point drawOffset;
|
|
|
|
Matrix transform;
|
|
|
|
if (!aSnapped) {
|
|
|
|
// If we are not snapped, we depend on the DT for translation.
|
|
|
|
drawOffset = aDrawOrigin;
|
|
|
|
transform = aDrawTarget->GetTransform().PreTranslate(aDrawOrigin);
|
|
|
|
} else {
|
|
|
|
// Otherwise, we only need to take the device offset into account.
|
|
|
|
drawOffset = aDrawOrigin - aContext->GetDeviceOffset();
|
|
|
|
transform = Matrix::Translation(drawOffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aScaleFactor != 1)
|
|
|
|
transform.PreScale(aScaleFactor, aScaleFactor);
|
|
|
|
|
|
|
|
cairo_matrix_t mat;
|
|
|
|
GfxMatrixToCairoMatrix(transform, mat);
|
|
|
|
|
2016-08-04 03:24:39 +03:00
|
|
|
nsIntSize clipSize((aDrawSize.width + aScaleFactor - 1) / aScaleFactor,
|
|
|
|
(aDrawSize.height + aScaleFactor - 1) / aScaleFactor);
|
|
|
|
|
2015-05-01 21:08:04 +03:00
|
|
|
#ifndef MOZ_TREE_CAIRO
|
|
|
|
// Directly use the Cairo draw target to render the widget if using system Cairo everywhere.
|
2015-06-12 21:19:34 +03:00
|
|
|
BorrowedCairoContext borrowCairo(aDrawTarget);
|
|
|
|
if (borrowCairo.mCairo) {
|
|
|
|
cairo_set_matrix(borrowCairo.mCairo, &mat);
|
2015-05-01 21:08:04 +03:00
|
|
|
|
2016-08-04 03:24:39 +03:00
|
|
|
cairo_new_path(borrowCairo.mCairo);
|
|
|
|
cairo_rectangle(borrowCairo.mCairo, 0, 0, clipSize.width, clipSize.height);
|
|
|
|
cairo_clip(borrowCairo.mCairo);
|
|
|
|
|
2015-06-12 21:19:34 +03:00
|
|
|
moz_gtk_widget_paint(aGTKWidgetType, borrowCairo.mCairo, &aGDKRect, &aState, aFlags, aDirection);
|
2015-05-01 21:08:04 +03:00
|
|
|
|
2015-06-12 21:19:34 +03:00
|
|
|
borrowCairo.Finish();
|
2015-05-01 21:08:04 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// A direct Cairo draw target is not available, so we need to create a temporary one.
|
|
|
|
#if defined(MOZ_X11) && defined(CAIRO_HAS_XLIB_SURFACE)
|
2015-06-09 20:46:09 +03:00
|
|
|
// If using a Cairo xlib surface, then try to reuse it.
|
|
|
|
BorrowedXlibDrawable borrow(aDrawTarget);
|
|
|
|
if (borrow.GetDrawable()) {
|
2016-01-13 21:11:07 +03:00
|
|
|
nsIntSize size = borrow.GetSize();
|
2015-06-09 20:46:09 +03:00
|
|
|
cairo_surface_t* surf = nullptr;
|
|
|
|
// Check if the surface is using XRender.
|
2015-05-01 21:08:04 +03:00
|
|
|
#ifdef CAIRO_HAS_XLIB_XRENDER_SURFACE
|
2015-06-09 20:46:09 +03:00
|
|
|
if (borrow.GetXRenderFormat()) {
|
|
|
|
surf = cairo_xlib_surface_create_with_xrender_format(
|
2015-05-01 21:08:04 +03:00
|
|
|
borrow.GetDisplay(), borrow.GetDrawable(), borrow.GetScreen(),
|
|
|
|
borrow.GetXRenderFormat(), size.width, size.height);
|
2015-06-09 20:46:09 +03:00
|
|
|
} else {
|
2015-05-01 21:08:04 +03:00
|
|
|
#else
|
|
|
|
if (! borrow.GetXRenderFormat()) {
|
|
|
|
#endif
|
|
|
|
surf = cairo_xlib_surface_create(
|
2015-06-09 20:46:09 +03:00
|
|
|
borrow.GetDisplay(), borrow.GetDrawable(), borrow.GetVisual(),
|
|
|
|
size.width, size.height);
|
2015-05-01 21:08:04 +03:00
|
|
|
}
|
|
|
|
if (!NS_WARN_IF(!surf)) {
|
2016-01-13 21:11:07 +03:00
|
|
|
Point offset = borrow.GetOffset();
|
|
|
|
if (offset != Point()) {
|
|
|
|
cairo_surface_set_device_offset(surf, offset.x, offset.y);
|
|
|
|
}
|
2015-05-01 21:08:04 +03:00
|
|
|
cairo_t* cr = cairo_create(surf);
|
|
|
|
if (!NS_WARN_IF(!cr)) {
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<SystemCairoClipper> clipper = new SystemCairoClipper(cr);
|
2015-06-09 20:46:09 +03:00
|
|
|
aContext->ExportClip(*clipper);
|
|
|
|
|
|
|
|
cairo_set_matrix(cr, &mat);
|
2015-05-01 21:08:04 +03:00
|
|
|
|
2016-08-04 03:24:39 +03:00
|
|
|
cairo_new_path(cr);
|
|
|
|
cairo_rectangle(cr, 0, 0, clipSize.width, clipSize.height);
|
|
|
|
cairo_clip(cr);
|
|
|
|
|
2015-05-01 21:08:04 +03:00
|
|
|
moz_gtk_widget_paint(aGTKWidgetType, cr, &aGDKRect, &aState, aFlags, aDirection);
|
|
|
|
|
|
|
|
cairo_destroy(cr);
|
|
|
|
}
|
|
|
|
cairo_surface_destroy(surf);
|
|
|
|
}
|
|
|
|
borrow.Finish();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Check if the widget requires complex masking that must be composited.
|
|
|
|
// Try to directly write to the draw target's pixels if possible.
|
|
|
|
uint8_t* data;
|
|
|
|
nsIntSize size;
|
|
|
|
int32_t stride;
|
|
|
|
SurfaceFormat format;
|
2016-01-13 21:11:07 +03:00
|
|
|
IntPoint origin;
|
|
|
|
if (aDrawTarget->LockBits(&data, &size, &stride, &format, &origin)) {
|
2015-05-01 21:08:04 +03:00
|
|
|
// Create a Cairo image surface context the device rectangle.
|
|
|
|
cairo_surface_t* surf =
|
|
|
|
cairo_image_surface_create_for_data(
|
2015-06-09 20:46:09 +03:00
|
|
|
data, GfxFormatToCairoFormat(format), size.width, size.height, stride);
|
2015-05-01 21:08:04 +03:00
|
|
|
if (!NS_WARN_IF(!surf)) {
|
2016-01-13 21:11:07 +03:00
|
|
|
if (origin != IntPoint()) {
|
|
|
|
cairo_surface_set_device_offset(surf, -origin.x, -origin.y);
|
|
|
|
}
|
2015-05-01 21:08:04 +03:00
|
|
|
cairo_t* cr = cairo_create(surf);
|
|
|
|
if (!NS_WARN_IF(!cr)) {
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<SystemCairoClipper> clipper = new SystemCairoClipper(cr);
|
2015-06-09 20:46:09 +03:00
|
|
|
aContext->ExportClip(*clipper);
|
|
|
|
|
|
|
|
cairo_set_matrix(cr, &mat);
|
2015-05-01 21:08:04 +03:00
|
|
|
|
2016-08-04 03:24:39 +03:00
|
|
|
cairo_new_path(cr);
|
|
|
|
cairo_rectangle(cr, 0, 0, clipSize.width, clipSize.height);
|
|
|
|
cairo_clip(cr);
|
|
|
|
|
2015-05-01 21:08:04 +03:00
|
|
|
moz_gtk_widget_paint(aGTKWidgetType, cr, &aGDKRect, &aState, aFlags, aDirection);
|
|
|
|
|
|
|
|
cairo_destroy(cr);
|
|
|
|
}
|
|
|
|
cairo_surface_destroy(surf);
|
|
|
|
}
|
|
|
|
aDrawTarget->ReleaseBits(data);
|
|
|
|
} else {
|
|
|
|
// If the widget has any transparency, make sure to choose an alpha format.
|
|
|
|
format = aTransparency != nsITheme::eOpaque ? SurfaceFormat::B8G8R8A8 : aDrawTarget->GetFormat();
|
|
|
|
// Create a temporary data surface to render the widget into.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<DataSourceSurface> dataSurface =
|
2015-05-01 21:08:04 +03:00
|
|
|
Factory::CreateDataSourceSurface(aDrawSize, format, aTransparency != nsITheme::eOpaque);
|
|
|
|
DataSourceSurface::MappedSurface map;
|
|
|
|
if (!NS_WARN_IF(!(dataSurface && dataSurface->Map(DataSourceSurface::MapType::WRITE, &map)))) {
|
|
|
|
// Create a Cairo image surface wrapping the data surface.
|
|
|
|
cairo_surface_t* surf =
|
|
|
|
cairo_image_surface_create_for_data(map.mData, GfxFormatToCairoFormat(format),
|
|
|
|
aDrawSize.width, aDrawSize.height, map.mStride);
|
|
|
|
cairo_t* cr = nullptr;
|
|
|
|
if (!NS_WARN_IF(!surf)) {
|
|
|
|
cr = cairo_create(surf);
|
|
|
|
if (!NS_WARN_IF(!cr)) {
|
|
|
|
if (aScaleFactor != 1) {
|
|
|
|
cairo_scale(cr, aScaleFactor, aScaleFactor);
|
|
|
|
}
|
|
|
|
|
|
|
|
moz_gtk_widget_paint(aGTKWidgetType, cr, &aGDKRect, &aState, aFlags, aDirection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unmap the surface before using it as a source
|
|
|
|
dataSurface->Unmap();
|
|
|
|
|
|
|
|
if (cr) {
|
2017-09-13 22:03:34 +03:00
|
|
|
// The widget either needs to be masked or has transparency, so use the slower drawing path.
|
|
|
|
aDrawTarget->DrawSurface(dataSurface,
|
|
|
|
Rect(aSnapped ? drawOffset - aDrawTarget->GetTransform().GetTranslation() : drawOffset,
|
|
|
|
Size(aDrawSize)),
|
|
|
|
Rect(0, 0, aDrawSize.width, aDrawSize.height));
|
2015-05-01 21:08:04 +03:00
|
|
|
cairo_destroy(cr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (surf) {
|
|
|
|
cairo_surface_destroy(surf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-02-23 04:01:29 +03:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2012-08-22 19:56:38 +04:00
|
|
|
nsNativeThemeGTK::GetExtraSizeForWidget(nsIFrame* aFrame, uint8_t aWidgetType,
|
2010-07-15 02:31:41 +04:00
|
|
|
nsIntMargin* aExtra)
|
2006-02-23 04:01:29 +03:00
|
|
|
{
|
|
|
|
*aExtra = nsIntMargin(0,0,0,0);
|
|
|
|
// Allow an extra one pixel above and below the thumb for certain
|
|
|
|
// GTK2 themes (Ximian Industrial, Bluecurve, Misty, at least);
|
2010-07-15 02:29:54 +04:00
|
|
|
// We modify the frame's overflow area. See bug 297508.
|
2006-02-23 04:01:29 +03:00
|
|
|
switch (aWidgetType) {
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCROLLBARTHUMB_VERTICAL:
|
2006-02-23 04:01:29 +03:00
|
|
|
aExtra->top = aExtra->bottom = 1;
|
2015-03-29 19:06:00 +03:00
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCROLLBARTHUMB_HORIZONTAL:
|
2006-02-23 04:01:29 +03:00
|
|
|
aExtra->left = aExtra->right = 1;
|
2015-03-29 19:06:00 +03:00
|
|
|
break;
|
2008-03-07 20:58:11 +03:00
|
|
|
|
2009-06-15 01:56:37 +04:00
|
|
|
case NS_THEME_BUTTON :
|
|
|
|
{
|
2010-07-15 02:31:41 +04:00
|
|
|
if (IsDefaultButton(aFrame)) {
|
2009-07-04 14:01:16 +04:00
|
|
|
// Some themes draw a default indicator outside the widget,
|
|
|
|
// include that in overflow
|
|
|
|
gint top, left, bottom, right;
|
|
|
|
moz_gtk_button_get_default_overflow(&top, &left, &bottom, &right);
|
|
|
|
aExtra->top = top;
|
|
|
|
aExtra->right = right;
|
|
|
|
aExtra->bottom = bottom;
|
|
|
|
aExtra->left = left;
|
2015-03-29 19:06:00 +03:00
|
|
|
break;
|
2009-07-04 14:01:16 +04:00
|
|
|
}
|
2016-01-23 09:44:06 +03:00
|
|
|
return false;
|
2009-06-15 01:56:37 +04:00
|
|
|
}
|
2014-06-14 16:48:08 +04:00
|
|
|
case NS_THEME_FOCUS_OUTLINE:
|
|
|
|
{
|
|
|
|
moz_gtk_get_focus_outline_size(&aExtra->left, &aExtra->top);
|
|
|
|
aExtra->right = aExtra->left;
|
|
|
|
aExtra->bottom = aExtra->top;
|
2015-03-29 19:06:00 +03:00
|
|
|
break;
|
2014-06-14 16:48:08 +04:00
|
|
|
}
|
2010-07-15 02:31:41 +04:00
|
|
|
case NS_THEME_TAB :
|
|
|
|
{
|
|
|
|
if (!IsSelectedTab(aFrame))
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2010-07-15 02:31:41 +04:00
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
gint gap_height = moz_gtk_get_tab_thickness(IsBottomTab(aFrame) ?
|
|
|
|
MOZ_GTK_TAB_BOTTOM : MOZ_GTK_TAB_TOP);
|
2015-04-30 08:31:00 +03:00
|
|
|
if (!gap_height)
|
|
|
|
return false;
|
2010-07-15 02:31:41 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t extra = gap_height - GetTabMarginPixels(aFrame);
|
2010-07-15 02:31:41 +04:00
|
|
|
if (extra <= 0)
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2010-07-15 02:31:41 +04:00
|
|
|
|
|
|
|
if (IsBottomTab(aFrame)) {
|
|
|
|
aExtra->top = extra;
|
|
|
|
} else {
|
|
|
|
aExtra->bottom = extra;
|
|
|
|
}
|
2016-01-23 09:44:06 +03:00
|
|
|
return false;
|
2010-07-15 02:31:41 +04:00
|
|
|
}
|
2006-02-23 04:01:29 +03:00
|
|
|
default:
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2006-02-23 04:01:29 +03:00
|
|
|
}
|
2018-01-18 13:52:59 +03:00
|
|
|
gint scale = GetMonitorScaleFactor(aFrame);
|
2015-04-23 19:35:00 +03:00
|
|
|
aExtra->top *= scale;
|
|
|
|
aExtra->right *= scale;
|
|
|
|
aExtra->bottom *= scale;
|
|
|
|
aExtra->left *= scale;
|
2015-03-29 19:06:00 +03:00
|
|
|
return true;
|
2006-02-23 04:01:29 +03:00
|
|
|
}
|
|
|
|
|
2005-08-20 11:13:04 +04:00
|
|
|
NS_IMETHODIMP
|
2017-06-09 22:14:53 +03:00
|
|
|
nsNativeThemeGTK::DrawWidgetBackground(gfxContext* aContext,
|
2005-08-20 11:13:04 +04:00
|
|
|
nsIFrame* aFrame,
|
2012-08-22 19:56:38 +04:00
|
|
|
uint8_t aWidgetType,
|
2005-08-20 11:13:04 +04:00
|
|
|
const nsRect& aRect,
|
2014-03-17 12:42:48 +04:00
|
|
|
const nsRect& aDirtyRect)
|
2005-08-20 11:13:04 +04:00
|
|
|
{
|
|
|
|
GtkWidgetState state;
|
2016-04-14 08:47:20 +03:00
|
|
|
WidgetNodeType gtkWidgetType;
|
2016-10-20 07:57:55 +03:00
|
|
|
GtkTextDirection direction = GetTextDirection(aFrame);
|
2005-08-20 11:13:04 +04:00
|
|
|
gint flags;
|
|
|
|
if (!GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, &state,
|
|
|
|
&flags))
|
|
|
|
return NS_OK;
|
2006-02-23 04:01:29 +03:00
|
|
|
|
2017-06-09 22:14:53 +03:00
|
|
|
gfxContext* ctx = aContext;
|
2008-07-25 03:01:59 +04:00
|
|
|
nsPresContext *presContext = aFrame->PresContext();
|
|
|
|
|
|
|
|
gfxRect rect = presContext->AppUnitsToGfxUnits(aRect);
|
|
|
|
gfxRect dirtyRect = presContext->AppUnitsToGfxUnits(aDirtyRect);
|
2018-01-18 13:52:59 +03:00
|
|
|
gint scaleFactor = GetMonitorScaleFactor(aFrame);
|
2008-07-25 03:01:59 +04:00
|
|
|
|
|
|
|
// Align to device pixels where sensible
|
|
|
|
// to provide crisper and faster drawing.
|
|
|
|
// Don't snap if it's a non-unit scale factor. We're going to have to take
|
|
|
|
// slow paths then in any case.
|
2015-05-01 21:08:04 +03:00
|
|
|
bool snapped = ctx->UserToDevicePixelSnapped(rect);
|
|
|
|
if (snapped) {
|
2008-07-25 03:01:59 +04:00
|
|
|
// Leave rect in device coords but make dirtyRect consistent.
|
|
|
|
dirtyRect = ctx->UserToDevice(dirtyRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Translate the dirty rect so that it is wrt the widget top-left.
|
2011-04-19 07:07:21 +04:00
|
|
|
dirtyRect.MoveBy(-rect.TopLeft());
|
2008-07-25 03:01:59 +04:00
|
|
|
// Round out the dirty rect to gdk pixels to ensure that gtk draws
|
|
|
|
// enough pixels for interpolation to device pixels.
|
|
|
|
dirtyRect.RoundOut();
|
|
|
|
|
|
|
|
// GTK themes can only draw an integer number of pixels
|
|
|
|
// (even when not snapped).
|
|
|
|
nsIntRect widgetRect(0, 0, NS_lround(rect.Width()), NS_lround(rect.Height()));
|
2010-07-15 02:25:41 +04:00
|
|
|
nsIntRect overflowRect(widgetRect);
|
|
|
|
nsIntMargin extraSize;
|
2010-07-15 02:31:41 +04:00
|
|
|
if (GetExtraSizeForWidget(aFrame, aWidgetType, &extraSize)) {
|
2015-11-04 20:40:16 +03:00
|
|
|
overflowRect.Inflate(extraSize);
|
2010-07-15 02:25:41 +04:00
|
|
|
}
|
2008-07-25 03:01:59 +04:00
|
|
|
|
|
|
|
// This is the rectangle that will actually be drawn, in gdk pixels
|
2012-08-22 19:56:38 +04:00
|
|
|
nsIntRect drawingRect(int32_t(dirtyRect.X()),
|
|
|
|
int32_t(dirtyRect.Y()),
|
|
|
|
int32_t(dirtyRect.Width()),
|
|
|
|
int32_t(dirtyRect.Height()));
|
2010-07-15 02:25:41 +04:00
|
|
|
if (widgetRect.IsEmpty()
|
|
|
|
|| !drawingRect.IntersectRect(overflowRect, drawingRect))
|
2008-07-25 03:01:59 +04:00
|
|
|
return NS_OK;
|
|
|
|
|
2005-10-06 08:02:10 +04:00
|
|
|
NS_ASSERTION(!IsWidgetTypeDisabled(mDisabledWidgetTypes, aWidgetType),
|
|
|
|
"Trying to render an unsafe widget!");
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool safeState = IsWidgetStateSafe(mSafeWidgetStates, aWidgetType, &state);
|
2005-10-06 08:02:10 +04:00
|
|
|
if (!safeState) {
|
2008-08-07 00:48:55 +04:00
|
|
|
gLastGdkError = 0;
|
|
|
|
gdk_error_trap_push ();
|
2005-10-06 08:02:10 +04:00
|
|
|
}
|
|
|
|
|
2015-05-01 21:08:04 +03:00
|
|
|
Transparency transparency = GetWidgetTransparency(aFrame, aWidgetType);
|
|
|
|
|
|
|
|
// gdk rectangles are wrt the drawing rect.
|
|
|
|
GdkRectangle gdk_rect = {-drawingRect.x/scaleFactor,
|
|
|
|
-drawingRect.y/scaleFactor,
|
|
|
|
widgetRect.width/scaleFactor,
|
|
|
|
widgetRect.height/scaleFactor};
|
|
|
|
|
2018-02-20 18:16:23 +03:00
|
|
|
// Save actual widget scale to GtkWidgetState as we don't provide
|
|
|
|
// nsFrame to gtk3drawing routines.
|
|
|
|
state.scale = scaleFactor;
|
|
|
|
|
2015-05-01 21:08:04 +03:00
|
|
|
// translate everything so (0,0) is the top left of the drawingRect
|
|
|
|
gfxPoint origin = rect.TopLeft() + drawingRect.TopLeft();
|
|
|
|
|
|
|
|
DrawThemeWithCairo(ctx, aContext->GetDrawTarget(),
|
|
|
|
state, gtkWidgetType, flags, direction, scaleFactor,
|
|
|
|
snapped, ToPoint(origin), drawingRect.Size(),
|
|
|
|
gdk_rect, transparency);
|
2005-10-06 08:02:10 +04:00
|
|
|
|
|
|
|
if (!safeState) {
|
2018-01-12 13:07:23 +03:00
|
|
|
// gdk_flush() call from expose event crashes Gtk+ on Wayland
|
|
|
|
// (Gnome BZ #773307)
|
|
|
|
if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
|
|
|
|
gdk_flush();
|
|
|
|
}
|
2008-08-07 00:48:55 +04:00
|
|
|
gLastGdkError = gdk_error_trap_pop ();
|
2005-10-06 08:02:10 +04:00
|
|
|
|
2008-08-07 00:48:55 +04:00
|
|
|
if (gLastGdkError) {
|
2005-10-06 08:02:10 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
printf("GTK theme failed for widget type %d, error was %d, state was "
|
2007-04-26 10:57:37 +04:00
|
|
|
"[active=%d,focused=%d,inHover=%d,disabled=%d]\n",
|
2008-08-07 00:48:55 +04:00
|
|
|
aWidgetType, gLastGdkError, state.active, state.focused,
|
2005-10-06 08:02:10 +04:00
|
|
|
state.inHover, state.disabled);
|
|
|
|
#endif
|
|
|
|
NS_WARNING("GTK theme failed; disabling unsafe widget");
|
|
|
|
SetWidgetTypeDisabled(mDisabledWidgetTypes, aWidgetType);
|
|
|
|
// force refresh of the window, because the widget was not
|
|
|
|
// successfully drawn it must be redrawn using the default look
|
|
|
|
RefreshWidgetWindow(aFrame);
|
|
|
|
} else {
|
|
|
|
SetWidgetStateSafe(mSafeWidgetStates, aWidgetType, &state);
|
|
|
|
}
|
|
|
|
}
|
2005-08-20 11:12:57 +04:00
|
|
|
|
2011-05-05 17:11:35 +04:00
|
|
|
// Indeterminate progress bar are animated.
|
2011-05-16 14:59:10 +04:00
|
|
|
if (gtkWidgetType == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
|
|
|
|
gtkWidgetType == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
|
2011-05-05 17:11:35 +04:00
|
|
|
if (!QueueAnimatedContentForRefresh(aFrame->GetContent(), 30)) {
|
|
|
|
NS_WARNING("unable to animate widget!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-20 11:11:46 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-01-22 16:01:09 +03:00
|
|
|
bool
|
|
|
|
nsNativeThemeGTK::CreateWebRenderCommandsForWidget(mozilla::wr::DisplayListBuilder& aBuilder,
|
|
|
|
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
|
|
|
const mozilla::layers::StackingContextHelper& aSc,
|
|
|
|
mozilla::layers::WebRenderLayerManager* aManager,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
uint8_t aWidgetType,
|
|
|
|
const nsRect& aRect)
|
|
|
|
{
|
|
|
|
nsPresContext* presContext = aFrame->PresContext();
|
|
|
|
wr::LayoutRect bounds = aSc.ToRelativeLayoutRect(
|
|
|
|
LayoutDeviceRect::FromAppUnits(aRect, presContext->AppUnitsPerDevPixel()));
|
|
|
|
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_WINDOW:
|
|
|
|
case NS_THEME_DIALOG:
|
|
|
|
aBuilder.PushRect(bounds, bounds, true,
|
|
|
|
wr::ToColorF(Color::FromABGR(
|
|
|
|
LookAndFeel::GetColor(LookAndFeel::eColorID_WindowBackground,
|
|
|
|
NS_RGBA(0, 0, 0, 0)))));
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
WidgetNodeType
|
|
|
|
nsNativeThemeGTK::NativeThemeToGtkTheme(uint8_t aWidgetType, nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
WidgetNodeType gtkWidgetType;
|
|
|
|
gint unusedFlags;
|
|
|
|
|
|
|
|
if (!GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, nullptr,
|
|
|
|
&unusedFlags))
|
|
|
|
{
|
|
|
|
MOZ_ASSERT_UNREACHABLE("Unknown native widget to gtk widget mapping");
|
|
|
|
return MOZ_GTK_WINDOW;
|
|
|
|
}
|
|
|
|
return gtkWidgetType;
|
|
|
|
}
|
|
|
|
|
2017-06-07 08:27:17 +03:00
|
|
|
void
|
|
|
|
nsNativeThemeGTK::GetCachedWidgetBorder(nsIFrame* aFrame, uint8_t aWidgetType,
|
|
|
|
GtkTextDirection aDirection,
|
|
|
|
nsIntMargin* aResult)
|
|
|
|
{
|
|
|
|
aResult->SizeTo(0, 0, 0, 0);
|
|
|
|
|
|
|
|
WidgetNodeType gtkWidgetType;
|
|
|
|
gint unusedFlags;
|
|
|
|
if (GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, nullptr,
|
|
|
|
&unusedFlags)) {
|
2017-06-07 08:27:18 +03:00
|
|
|
MOZ_ASSERT(0 <= gtkWidgetType && gtkWidgetType < MOZ_GTK_WIDGET_NODE_COUNT);
|
|
|
|
uint8_t cacheIndex = gtkWidgetType / 8;
|
|
|
|
uint8_t cacheBit = 1u << (gtkWidgetType % 8);
|
|
|
|
|
|
|
|
if (mBorderCacheValid[cacheIndex] & cacheBit) {
|
|
|
|
*aResult = mBorderCache[gtkWidgetType];
|
|
|
|
} else {
|
|
|
|
moz_gtk_get_widget_border(gtkWidgetType, &aResult->left, &aResult->top,
|
|
|
|
&aResult->right, &aResult->bottom, aDirection);
|
|
|
|
if (aWidgetType != MOZ_GTK_DROPDOWN) { // depends on aDirection
|
|
|
|
mBorderCacheValid[cacheIndex] |= cacheBit;
|
|
|
|
mBorderCache[gtkWidgetType] = *aResult;
|
|
|
|
}
|
|
|
|
}
|
2017-06-07 08:27:17 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-20 11:11:46 +04:00
|
|
|
NS_IMETHODIMP
|
2011-04-17 05:22:44 +04:00
|
|
|
nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
|
2012-08-22 19:56:38 +04:00
|
|
|
uint8_t aWidgetType, nsIntMargin* aResult)
|
2005-08-20 11:11:46 +04:00
|
|
|
{
|
2007-12-21 14:51:48 +03:00
|
|
|
GtkTextDirection direction = GetTextDirection(aFrame);
|
2007-06-05 07:26:43 +04:00
|
|
|
aResult->top = aResult->left = aResult->right = aResult->bottom = 0;
|
2005-08-20 11:13:05 +04:00
|
|
|
switch (aWidgetType) {
|
2017-03-27 21:32:25 +03:00
|
|
|
case NS_THEME_SCROLLBAR_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_VERTICAL:
|
|
|
|
{
|
|
|
|
GtkOrientation orientation =
|
|
|
|
aWidgetType == NS_THEME_SCROLLBAR_HORIZONTAL ?
|
|
|
|
GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
|
|
|
|
const ScrollbarGTKMetrics* metrics = GetScrollbarMetrics(orientation);
|
|
|
|
|
|
|
|
const GtkBorder& border = metrics->border.scrollbar;
|
|
|
|
aResult->top = border.top;
|
|
|
|
aResult->right = border.right;
|
|
|
|
aResult->bottom = border.bottom;
|
|
|
|
aResult->left = border.left;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NS_THEME_SCROLLBARTRACK_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBARTRACK_VERTICAL:
|
|
|
|
{
|
|
|
|
GtkOrientation orientation =
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARTRACK_HORIZONTAL ?
|
|
|
|
GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
|
|
|
|
const ScrollbarGTKMetrics* metrics = GetScrollbarMetrics(orientation);
|
|
|
|
|
|
|
|
const GtkBorder& border = metrics->border.track;
|
|
|
|
aResult->top = border.top;
|
|
|
|
aResult->right = border.right;
|
|
|
|
aResult->bottom = border.bottom;
|
|
|
|
aResult->left = border.left;
|
|
|
|
}
|
|
|
|
break;
|
2005-08-20 11:13:05 +04:00
|
|
|
case NS_THEME_TOOLBOX:
|
|
|
|
// gtk has no toolbox equivalent. So, although we map toolbox to
|
|
|
|
// gtk's 'toolbar' for purposes of painting the widget background,
|
|
|
|
// we don't use the toolbar border for toolbox.
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_DUALBUTTON:
|
2005-08-20 11:14:07 +04:00
|
|
|
// TOOLBAR_DUAL_BUTTON is an interesting case. We want a border to draw
|
|
|
|
// around the entire button + dropdown, and also an inner border if you're
|
|
|
|
// over the button part. But, we want the inner button to be right up
|
|
|
|
// against the edge of the outer button so that the borders overlap.
|
|
|
|
// To make this happen, we draw a button border for the outer button,
|
|
|
|
// but don't reserve any space for it.
|
|
|
|
break;
|
2007-12-21 14:51:48 +03:00
|
|
|
case NS_THEME_TAB:
|
2014-09-04 07:17:00 +04:00
|
|
|
{
|
2016-04-14 08:47:20 +03:00
|
|
|
WidgetNodeType gtkWidgetType;
|
2014-09-04 07:17:00 +04:00
|
|
|
gint flags;
|
|
|
|
|
|
|
|
if (!GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, nullptr,
|
|
|
|
&flags))
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
moz_gtk_get_tab_border(&aResult->left, &aResult->top,
|
|
|
|
&aResult->right, &aResult->bottom, direction,
|
2016-08-22 06:13:00 +03:00
|
|
|
(GtkTabFlags)flags, gtkWidgetType);
|
2014-09-04 07:17:00 +04:00
|
|
|
}
|
2007-12-21 14:51:48 +03:00
|
|
|
break;
|
2011-06-25 01:00:50 +04:00
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
case NS_THEME_RADIOMENUITEM:
|
|
|
|
// For regular menuitems, we will be using GetWidgetPadding instead of
|
|
|
|
// GetWidgetBorder to pad up the widget's internals; other menuitems
|
|
|
|
// will need to fall through and use the default case as before.
|
|
|
|
if (IsRegularMenuItem(aFrame))
|
|
|
|
break;
|
2016-01-23 09:44:06 +03:00
|
|
|
MOZ_FALLTHROUGH;
|
2005-08-20 11:13:05 +04:00
|
|
|
default:
|
|
|
|
{
|
2017-06-07 08:27:17 +03:00
|
|
|
GetCachedWidgetBorder(aFrame, aWidgetType, direction, aResult);
|
2005-08-20 11:12:11 +04:00
|
|
|
}
|
2005-08-20 11:13:05 +04:00
|
|
|
}
|
2015-04-28 07:22:00 +03:00
|
|
|
|
2018-01-18 13:52:59 +03:00
|
|
|
gint scale = GetMonitorScaleFactor(aFrame);
|
2015-04-28 07:22:00 +03:00
|
|
|
aResult->top *= scale;
|
|
|
|
aResult->right *= scale;
|
|
|
|
aResult->bottom *= scale;
|
|
|
|
aResult->left *= scale;
|
2005-08-20 11:11:46 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2011-04-17 05:22:44 +04:00
|
|
|
nsNativeThemeGTK::GetWidgetPadding(nsDeviceContext* aContext,
|
2012-08-22 19:56:38 +04:00
|
|
|
nsIFrame* aFrame, uint8_t aWidgetType,
|
2009-01-15 06:27:09 +03:00
|
|
|
nsIntMargin* aResult)
|
2005-08-20 11:14:07 +04:00
|
|
|
{
|
2008-03-07 20:57:34 +03:00
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_BUTTON_FOCUS:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TOOLBARBUTTON:
|
2017-12-13 13:02:51 +03:00
|
|
|
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
|
|
|
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
|
|
|
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
|
|
|
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_DUALBUTTON:
|
|
|
|
case NS_THEME_TAB_SCROLL_ARROW_BACK:
|
|
|
|
case NS_THEME_TAB_SCROLL_ARROW_FORWARD:
|
|
|
|
case NS_THEME_MENULIST_BUTTON:
|
|
|
|
case NS_THEME_TOOLBARBUTTON_DROPDOWN:
|
2010-07-27 18:57:47 +04:00
|
|
|
case NS_THEME_BUTTON_ARROW_UP:
|
|
|
|
case NS_THEME_BUTTON_ARROW_DOWN:
|
|
|
|
case NS_THEME_BUTTON_ARROW_NEXT:
|
|
|
|
case NS_THEME_BUTTON_ARROW_PREVIOUS:
|
2013-03-29 00:25:05 +04:00
|
|
|
case NS_THEME_RANGE_THUMB:
|
2008-03-07 20:57:34 +03:00
|
|
|
// Radios and checkboxes return a fixed size in GetMinimumWidgetSize
|
|
|
|
// and have a meaningful baseline, so they can't have
|
|
|
|
// author-specified padding.
|
|
|
|
case NS_THEME_CHECKBOX:
|
|
|
|
case NS_THEME_RADIO:
|
|
|
|
aResult->SizeTo(0, 0, 0, 0);
|
2011-10-03 11:56:21 +04:00
|
|
|
return true;
|
2011-06-25 01:00:46 +04:00
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
case NS_THEME_RADIOMENUITEM:
|
|
|
|
{
|
|
|
|
// Menubar and menulist have their padding specified in CSS.
|
|
|
|
if (!IsRegularMenuItem(aFrame))
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2011-06-25 01:00:46 +04:00
|
|
|
|
2017-06-07 08:27:17 +03:00
|
|
|
GetCachedWidgetBorder(aFrame, aWidgetType, GetTextDirection(aFrame),
|
|
|
|
aResult);
|
2011-06-25 01:00:50 +04:00
|
|
|
|
2011-06-25 01:00:46 +04:00
|
|
|
gint horizontal_padding;
|
|
|
|
|
|
|
|
if (aWidgetType == NS_THEME_MENUITEM)
|
|
|
|
moz_gtk_menuitem_get_horizontal_padding(&horizontal_padding);
|
|
|
|
else
|
|
|
|
moz_gtk_checkmenuitem_get_horizontal_padding(&horizontal_padding);
|
2011-06-25 01:00:50 +04:00
|
|
|
|
|
|
|
aResult->left += horizontal_padding;
|
|
|
|
aResult->right += horizontal_padding;
|
|
|
|
|
2018-01-18 13:52:59 +03:00
|
|
|
gint scale = GetMonitorScaleFactor(aFrame);
|
2015-04-23 19:35:00 +03:00
|
|
|
aResult->top *= scale;
|
|
|
|
aResult->right *= scale;
|
|
|
|
aResult->bottom *= scale;
|
|
|
|
aResult->left *= scale;
|
2015-03-29 19:06:00 +03:00
|
|
|
|
2011-10-03 11:56:21 +04:00
|
|
|
return true;
|
2011-06-25 01:00:46 +04:00
|
|
|
}
|
2005-08-20 11:14:07 +04:00
|
|
|
}
|
|
|
|
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2005-08-20 11:14:07 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2011-04-17 05:22:44 +04:00
|
|
|
nsNativeThemeGTK::GetWidgetOverflow(nsDeviceContext* aContext,
|
2012-08-22 19:56:38 +04:00
|
|
|
nsIFrame* aFrame, uint8_t aWidgetType,
|
2008-04-02 03:34:20 +04:00
|
|
|
nsRect* aOverflowRect)
|
2005-09-01 01:00:52 +04:00
|
|
|
{
|
2010-07-15 02:31:41 +04:00
|
|
|
nsIntMargin extraSize;
|
|
|
|
if (!GetExtraSizeForWidget(aFrame, aWidgetType, &extraSize))
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2008-01-09 10:40:21 +03:00
|
|
|
|
2013-03-06 12:05:55 +04:00
|
|
|
int32_t p2a = aContext->AppUnitsPerDevPixel();
|
|
|
|
nsMargin m(NSIntPixelsToAppUnits(extraSize.top, p2a),
|
|
|
|
NSIntPixelsToAppUnits(extraSize.right, p2a),
|
|
|
|
NSIntPixelsToAppUnits(extraSize.bottom, p2a),
|
|
|
|
NSIntPixelsToAppUnits(extraSize.left, p2a));
|
2007-12-21 14:51:48 +03:00
|
|
|
|
2008-04-02 03:34:20 +04:00
|
|
|
aOverflowRect->Inflate(m);
|
2011-10-03 11:56:21 +04:00
|
|
|
return true;
|
2005-09-01 01:00:52 +04:00
|
|
|
}
|
|
|
|
|
2005-08-20 11:11:46 +04:00
|
|
|
NS_IMETHODIMP
|
2014-06-27 13:19:00 +04:00
|
|
|
nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
|
2012-08-22 19:56:38 +04:00
|
|
|
nsIFrame* aFrame, uint8_t aWidgetType,
|
2015-03-30 18:36:14 +03:00
|
|
|
LayoutDeviceIntSize* aResult,
|
|
|
|
bool* aIsOverridable)
|
2005-08-20 11:11:46 +04:00
|
|
|
{
|
|
|
|
aResult->width = aResult->height = 0;
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = true;
|
2005-08-20 11:11:48 +04:00
|
|
|
|
|
|
|
switch (aWidgetType) {
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCROLLBARBUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBARBUTTON_DOWN:
|
2005-08-20 11:11:48 +04:00
|
|
|
{
|
2017-03-27 21:32:25 +03:00
|
|
|
const ScrollbarGTKMetrics* metrics =
|
|
|
|
GetScrollbarMetrics(GTK_ORIENTATION_VERTICAL);
|
2005-08-20 11:12:11 +04:00
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
aResult->width = metrics->size.button.width;
|
|
|
|
aResult->height = metrics->size.button.height;
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = false;
|
2005-08-20 11:11:48 +04:00
|
|
|
}
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCROLLBARBUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBARBUTTON_RIGHT:
|
2005-08-20 11:14:20 +04:00
|
|
|
{
|
2017-03-27 21:32:25 +03:00
|
|
|
const ScrollbarGTKMetrics* metrics =
|
|
|
|
GetScrollbarMetrics(GTK_ORIENTATION_HORIZONTAL);
|
2005-08-20 11:14:20 +04:00
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
aResult->width = metrics->size.button.width;
|
|
|
|
aResult->height = metrics->size.button.height;
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = false;
|
2005-08-20 11:14:20 +04:00
|
|
|
}
|
|
|
|
break;
|
2007-12-21 14:17:01 +03:00
|
|
|
case NS_THEME_SPLITTER:
|
|
|
|
{
|
|
|
|
gint metrics;
|
|
|
|
if (IsHorizontal(aFrame)) {
|
|
|
|
moz_gtk_splitter_get_metrics(GTK_ORIENTATION_HORIZONTAL, &metrics);
|
|
|
|
aResult->width = metrics;
|
|
|
|
aResult->height = 0;
|
|
|
|
} else {
|
|
|
|
moz_gtk_splitter_get_metrics(GTK_ORIENTATION_VERTICAL, &metrics);
|
|
|
|
aResult->width = 0;
|
|
|
|
aResult->height = metrics;
|
|
|
|
}
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = false;
|
2007-12-21 14:17:01 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-12-22 07:05:00 +03:00
|
|
|
case NS_THEME_SCROLLBAR_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_VERTICAL:
|
2011-05-16 07:28:01 +04:00
|
|
|
{
|
2016-10-25 18:27:00 +03:00
|
|
|
/* While we enforce a minimum size for the thumb, this is ignored
|
|
|
|
* for the some scrollbars if buttons are hidden (bug 513006) because
|
|
|
|
* the thumb isn't a direct child of the scrollbar, unlike the buttons
|
|
|
|
* or track. So add a minimum size to the track as well to prevent a
|
|
|
|
* 0-width scrollbar. */
|
2017-03-27 21:32:25 +03:00
|
|
|
GtkOrientation orientation =
|
|
|
|
aWidgetType == NS_THEME_SCROLLBAR_HORIZONTAL ?
|
|
|
|
GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
|
|
|
|
const ScrollbarGTKMetrics* metrics = GetScrollbarMetrics(orientation);
|
2011-05-16 07:28:01 +04:00
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
aResult->width = metrics->size.scrollbar.width;
|
|
|
|
aResult->height = metrics->size.scrollbar.height;
|
2011-05-16 07:28:01 +04:00
|
|
|
}
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCROLLBARTHUMB_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBARTHUMB_HORIZONTAL:
|
2005-08-20 11:11:48 +04:00
|
|
|
{
|
2017-03-27 21:32:25 +03:00
|
|
|
GtkOrientation orientation =
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL ?
|
|
|
|
GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
|
|
|
|
const ScrollbarGTKMetrics* metrics = GetScrollbarMetrics(orientation);
|
|
|
|
|
|
|
|
aResult->width = metrics->size.thumb.width;
|
|
|
|
aResult->height = metrics->size.thumb.height;
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = false;
|
2005-08-20 11:11:48 +04:00
|
|
|
}
|
|
|
|
break;
|
2013-03-29 00:25:05 +04:00
|
|
|
case NS_THEME_RANGE_THUMB:
|
|
|
|
{
|
|
|
|
gint thumb_length, thumb_height;
|
|
|
|
|
|
|
|
if (IsRangeHorizontal(aFrame)) {
|
|
|
|
moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_HORIZONTAL, &thumb_length, &thumb_height);
|
|
|
|
} else {
|
|
|
|
moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_VERTICAL, &thumb_height, &thumb_length);
|
|
|
|
}
|
|
|
|
aResult->width = thumb_length;
|
|
|
|
aResult->height = thumb_height;
|
|
|
|
|
|
|
|
*aIsOverridable = false;
|
|
|
|
}
|
|
|
|
break;
|
2015-07-30 12:29:00 +03:00
|
|
|
case NS_THEME_RANGE:
|
|
|
|
{
|
|
|
|
gint scale_width, scale_height;
|
|
|
|
|
|
|
|
moz_gtk_get_scale_metrics(IsRangeHorizontal(aFrame) ?
|
|
|
|
GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL,
|
|
|
|
&scale_width, &scale_height);
|
|
|
|
aResult->width = scale_width;
|
|
|
|
aResult->height = scale_height;
|
|
|
|
|
|
|
|
*aIsOverridable = true;
|
|
|
|
}
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCALETHUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALETHUMB_VERTICAL:
|
2006-05-30 17:50:48 +04:00
|
|
|
{
|
|
|
|
gint thumb_length, thumb_height;
|
|
|
|
|
2016-05-18 20:29:56 +03:00
|
|
|
if (aWidgetType == NS_THEME_SCALETHUMB_VERTICAL) {
|
2006-05-30 17:50:48 +04:00
|
|
|
moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_VERTICAL, &thumb_length, &thumb_height);
|
|
|
|
aResult->width = thumb_height;
|
|
|
|
aResult->height = thumb_length;
|
|
|
|
} else {
|
|
|
|
moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_HORIZONTAL, &thumb_length, &thumb_height);
|
|
|
|
aResult->width = thumb_length;
|
|
|
|
aResult->height = thumb_height;
|
|
|
|
}
|
|
|
|
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = false;
|
2006-05-30 17:50:48 +04:00
|
|
|
}
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TAB_SCROLL_ARROW_BACK:
|
|
|
|
case NS_THEME_TAB_SCROLL_ARROW_FORWARD:
|
2008-02-15 08:28:44 +03:00
|
|
|
{
|
|
|
|
moz_gtk_get_tab_scroll_arrow_size(&aResult->width, &aResult->height);
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = false;
|
2008-02-15 08:28:44 +03:00
|
|
|
}
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_MENULIST_BUTTON:
|
2005-08-20 11:12:17 +04:00
|
|
|
{
|
2008-03-12 13:54:22 +03:00
|
|
|
moz_gtk_get_combo_box_entry_button_size(&aResult->width,
|
|
|
|
&aResult->height);
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = false;
|
2005-08-20 11:12:22 +04:00
|
|
|
}
|
|
|
|
break;
|
2007-12-11 12:09:09 +03:00
|
|
|
case NS_THEME_MENUSEPARATOR:
|
|
|
|
{
|
|
|
|
gint separator_height;
|
|
|
|
|
|
|
|
moz_gtk_get_menu_separator_height(&separator_height);
|
|
|
|
aResult->height = separator_height;
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = false;
|
2007-12-11 12:09:09 +03:00
|
|
|
}
|
|
|
|
break;
|
2005-08-20 11:12:22 +04:00
|
|
|
case NS_THEME_CHECKBOX:
|
|
|
|
case NS_THEME_RADIO:
|
|
|
|
{
|
2017-10-10 14:35:56 +03:00
|
|
|
const ToggleGTKMetrics* metrics = GetToggleMetrics(aWidgetType == NS_THEME_RADIO);
|
|
|
|
aResult->width = metrics->minSizeWithBorder.width;
|
|
|
|
aResult->height = metrics->minSizeWithBorder.height;
|
2005-08-20 11:12:17 +04:00
|
|
|
}
|
2005-08-20 11:12:19 +04:00
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TOOLBARBUTTON_DROPDOWN:
|
2010-07-27 18:57:47 +04:00
|
|
|
case NS_THEME_BUTTON_ARROW_UP:
|
|
|
|
case NS_THEME_BUTTON_ARROW_DOWN:
|
|
|
|
case NS_THEME_BUTTON_ARROW_NEXT:
|
|
|
|
case NS_THEME_BUTTON_ARROW_PREVIOUS:
|
2008-03-12 20:27:03 +03:00
|
|
|
{
|
2016-03-01 03:12:03 +03:00
|
|
|
moz_gtk_get_arrow_size(MOZ_GTK_TOOLBARBUTTON_ARROW,
|
|
|
|
&aResult->width, &aResult->height);
|
|
|
|
*aIsOverridable = false;
|
2008-03-12 20:27:03 +03:00
|
|
|
}
|
|
|
|
break;
|
2018-01-22 14:09:09 +03:00
|
|
|
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
2018-01-25 13:13:12 +03:00
|
|
|
{
|
|
|
|
const ToolbarButtonGTKMetrics* metrics =
|
|
|
|
GetToolbarButtonMetrics(MOZ_GTK_HEADER_BAR_BUTTON_CLOSE);
|
|
|
|
aResult->width = metrics->minSizeWithBorderMargin.width;
|
|
|
|
aResult->height = metrics->minSizeWithBorderMargin.height;
|
|
|
|
break;
|
|
|
|
}
|
2018-01-22 14:09:09 +03:00
|
|
|
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
2018-01-25 13:13:12 +03:00
|
|
|
{
|
|
|
|
const ToolbarButtonGTKMetrics* metrics =
|
|
|
|
GetToolbarButtonMetrics(MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE);
|
|
|
|
aResult->width = metrics->minSizeWithBorderMargin.width;
|
|
|
|
aResult->height = metrics->minSizeWithBorderMargin.height;
|
|
|
|
break;
|
|
|
|
}
|
2018-01-22 14:09:09 +03:00
|
|
|
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
2018-01-25 13:13:12 +03:00
|
|
|
{
|
|
|
|
const ToolbarButtonGTKMetrics* metrics =
|
|
|
|
GetToolbarButtonMetrics(MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE);
|
|
|
|
aResult->width = metrics->minSizeWithBorderMargin.width;
|
|
|
|
aResult->height = metrics->minSizeWithBorderMargin.height;
|
|
|
|
break;
|
|
|
|
}
|
2018-01-22 14:09:09 +03:00
|
|
|
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
|
|
|
{
|
2018-01-25 13:13:12 +03:00
|
|
|
const ToolbarButtonGTKMetrics* metrics =
|
|
|
|
GetToolbarButtonMetrics(MOZ_GTK_HEADER_BAR_BUTTON_RESTORE);
|
2018-01-22 14:09:09 +03:00
|
|
|
aResult->width = metrics->minSizeWithBorderMargin.width;
|
|
|
|
aResult->height = metrics->minSizeWithBorderMargin.height;
|
|
|
|
break;
|
|
|
|
}
|
2005-08-20 11:14:00 +04:00
|
|
|
case NS_THEME_CHECKBOX_CONTAINER:
|
|
|
|
case NS_THEME_RADIO_CONTAINER:
|
|
|
|
case NS_THEME_CHECKBOX_LABEL:
|
|
|
|
case NS_THEME_RADIO_LABEL:
|
2005-08-20 11:14:07 +04:00
|
|
|
case NS_THEME_BUTTON:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_MENULIST:
|
|
|
|
case NS_THEME_TOOLBARBUTTON:
|
|
|
|
case NS_THEME_TREEHEADERCELL:
|
2005-08-20 11:14:00 +04:00
|
|
|
{
|
2016-05-18 20:29:56 +03:00
|
|
|
if (aWidgetType == NS_THEME_MENULIST) {
|
2016-03-01 03:12:03 +03:00
|
|
|
// Include the arrow size.
|
|
|
|
moz_gtk_get_arrow_size(MOZ_GTK_DROPDOWN,
|
|
|
|
&aResult->width, &aResult->height);
|
|
|
|
}
|
|
|
|
// else the minimum size is missing consideration of container
|
|
|
|
// descendants; the value returned here will not be helpful, but the
|
|
|
|
// box model may consider border and padding with child minimum sizes.
|
|
|
|
|
2009-01-15 06:27:09 +03:00
|
|
|
nsIntMargin border;
|
2018-01-18 13:52:59 +03:00
|
|
|
GetCachedWidgetBorder(aFrame, aWidgetType, GetTextDirection(aFrame), &border);
|
2016-03-01 03:12:03 +03:00
|
|
|
aResult->width += border.left + border.right;
|
|
|
|
aResult->height += border.top + border.bottom;
|
2005-08-20 11:14:00 +04:00
|
|
|
}
|
|
|
|
break;
|
2018-01-09 13:51:07 +03:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
2016-04-01 05:43:00 +03:00
|
|
|
case NS_THEME_NUMBER_INPUT:
|
|
|
|
case NS_THEME_TEXTFIELD:
|
|
|
|
{
|
|
|
|
moz_gtk_get_entry_min_height(&aResult->height);
|
|
|
|
}
|
|
|
|
break;
|
2016-04-08 02:25:24 +03:00
|
|
|
#endif
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SEPARATOR:
|
2007-12-03 12:13:29 +03:00
|
|
|
{
|
|
|
|
gint separator_width;
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2007-12-03 12:13:29 +03:00
|
|
|
moz_gtk_get_toolbar_separator_width(&separator_width);
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2007-12-03 12:13:29 +03:00
|
|
|
aResult->width = separator_width;
|
|
|
|
}
|
|
|
|
break;
|
2017-11-29 05:43:13 +03:00
|
|
|
case NS_THEME_INNER_SPIN_BUTTON:
|
2007-12-21 14:30:29 +03:00
|
|
|
case NS_THEME_SPINNER:
|
|
|
|
// hard code these sizes
|
|
|
|
aResult->width = 14;
|
|
|
|
aResult->height = 26;
|
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TREEHEADERSORTARROW:
|
|
|
|
case NS_THEME_SPINNER_UPBUTTON:
|
|
|
|
case NS_THEME_SPINNER_DOWNBUTTON:
|
2006-07-13 21:40:49 +04:00
|
|
|
// hard code these sizes
|
|
|
|
aResult->width = 14;
|
|
|
|
aResult->height = 13;
|
|
|
|
break;
|
2007-12-11 13:08:35 +03:00
|
|
|
case NS_THEME_RESIZER:
|
|
|
|
// same as Windows to make our lives easier
|
|
|
|
aResult->width = aResult->height = 15;
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = false;
|
2007-12-11 13:08:35 +03:00
|
|
|
break;
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TREETWISTY:
|
|
|
|
case NS_THEME_TREETWISTYOPEN:
|
2007-11-15 06:47:16 +03:00
|
|
|
{
|
|
|
|
gint expander_size;
|
|
|
|
|
2008-01-03 10:07:32 +03:00
|
|
|
moz_gtk_get_treeview_expander_size(&expander_size);
|
2007-11-15 06:47:16 +03:00
|
|
|
aResult->width = aResult->height = expander_size;
|
2011-10-03 11:56:21 +04:00
|
|
|
*aIsOverridable = false;
|
2007-11-15 06:47:16 +03:00
|
|
|
}
|
|
|
|
break;
|
2005-08-20 11:11:48 +04:00
|
|
|
}
|
2015-03-29 19:06:00 +03:00
|
|
|
|
2018-01-18 13:52:59 +03:00
|
|
|
*aResult = *aResult * GetMonitorScaleFactor(aFrame);
|
2015-03-29 19:06:00 +03:00
|
|
|
|
2005-08-20 11:11:46 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2017-12-19 13:38:59 +03:00
|
|
|
nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
|
2017-10-03 01:05:19 +03:00
|
|
|
nsAtom* aAttribute, bool* aShouldRepaint,
|
2016-04-21 02:49:09 +03:00
|
|
|
const nsAttrValue* aOldValue)
|
2005-08-20 11:11:46 +04:00
|
|
|
{
|
|
|
|
// Some widget types just never change state.
|
2005-08-20 11:13:04 +04:00
|
|
|
if (aWidgetType == NS_THEME_TOOLBOX ||
|
|
|
|
aWidgetType == NS_THEME_TOOLBAR ||
|
|
|
|
aWidgetType == NS_THEME_STATUSBAR ||
|
2016-05-18 20:29:56 +03:00
|
|
|
aWidgetType == NS_THEME_STATUSBARPANEL ||
|
2016-05-19 11:58:00 +03:00
|
|
|
aWidgetType == NS_THEME_RESIZERPANEL ||
|
2016-05-18 20:29:56 +03:00
|
|
|
aWidgetType == NS_THEME_PROGRESSCHUNK ||
|
|
|
|
aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL ||
|
2005-08-20 11:11:46 +04:00
|
|
|
aWidgetType == NS_THEME_PROGRESSBAR ||
|
|
|
|
aWidgetType == NS_THEME_PROGRESSBAR_VERTICAL ||
|
2005-08-20 11:13:48 +04:00
|
|
|
aWidgetType == NS_THEME_MENUBAR ||
|
|
|
|
aWidgetType == NS_THEME_MENUPOPUP ||
|
2005-08-20 11:13:45 +04:00
|
|
|
aWidgetType == NS_THEME_TOOLTIP ||
|
2007-12-11 12:09:09 +03:00
|
|
|
aWidgetType == NS_THEME_MENUSEPARATOR ||
|
2005-08-20 11:13:45 +04:00
|
|
|
aWidgetType == NS_THEME_WINDOW ||
|
|
|
|
aWidgetType == NS_THEME_DIALOG) {
|
2011-10-03 11:56:21 +04:00
|
|
|
*aShouldRepaint = false;
|
2005-08-20 11:11:46 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-05-18 20:29:56 +03:00
|
|
|
if ((aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL) &&
|
2014-08-13 14:02:00 +04:00
|
|
|
aAttribute == nsGkAtoms::active) {
|
|
|
|
*aShouldRepaint = true;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-05-18 20:29:56 +03:00
|
|
|
if ((aWidgetType == NS_THEME_SCROLLBARBUTTON_UP ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT ||
|
|
|
|
aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT) &&
|
2011-10-14 22:11:22 +04:00
|
|
|
(aAttribute == nsGkAtoms::curpos ||
|
|
|
|
aAttribute == nsGkAtoms::maxpos)) {
|
2016-04-21 02:49:09 +03:00
|
|
|
// If 'curpos' has changed and we are passed its old value, we can
|
|
|
|
// determine whether the button's enablement actually needs to change.
|
|
|
|
if (aAttribute == nsGkAtoms::curpos && aOldValue) {
|
|
|
|
int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0);
|
|
|
|
int32_t maxpos = CheckIntAttr(aFrame, nsGkAtoms::maxpos, 0);
|
|
|
|
nsAutoString str;
|
|
|
|
aOldValue->ToString(str);
|
|
|
|
nsresult err;
|
|
|
|
int32_t oldCurpos = str.ToInteger(&err);
|
|
|
|
if (str.IsEmpty() || NS_FAILED(err)) {
|
|
|
|
*aShouldRepaint = true;
|
|
|
|
} else {
|
|
|
|
bool disabledBefore = ShouldScrollbarButtonBeDisabled(oldCurpos, maxpos, aWidgetType);
|
|
|
|
bool disabledNow = ShouldScrollbarButtonBeDisabled(curpos, maxpos, aWidgetType);
|
|
|
|
*aShouldRepaint = (disabledBefore != disabledNow);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
*aShouldRepaint = true;
|
|
|
|
}
|
2008-02-07 12:26:22 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-20 11:11:46 +04:00
|
|
|
// XXXdwh Not sure what can really be done here. Can at least guess for
|
|
|
|
// specific widgets that they're highly unlikely to have certain states.
|
|
|
|
// For example, a toolbar doesn't care about any states.
|
|
|
|
if (!aAttribute) {
|
|
|
|
// Hover/focus/active changed. Always repaint.
|
2011-10-03 11:56:21 +04:00
|
|
|
*aShouldRepaint = true;
|
2005-08-20 11:11:46 +04:00
|
|
|
}
|
|
|
|
else {
|
2017-12-19 13:38:59 +03:00
|
|
|
// Check the attribute to see if it's relevant.
|
2005-08-20 11:11:46 +04:00
|
|
|
// disabled, checked, dlgtype, default, etc.
|
2011-10-03 11:56:21 +04:00
|
|
|
*aShouldRepaint = false;
|
2011-10-14 22:11:22 +04:00
|
|
|
if (aAttribute == nsGkAtoms::disabled ||
|
|
|
|
aAttribute == nsGkAtoms::checked ||
|
|
|
|
aAttribute == nsGkAtoms::selected ||
|
2015-03-16 21:30:41 +03:00
|
|
|
aAttribute == nsGkAtoms::visuallyselected ||
|
2011-10-14 22:11:22 +04:00
|
|
|
aAttribute == nsGkAtoms::focused ||
|
|
|
|
aAttribute == nsGkAtoms::readonly ||
|
|
|
|
aAttribute == nsGkAtoms::_default ||
|
|
|
|
aAttribute == nsGkAtoms::menuactive ||
|
|
|
|
aAttribute == nsGkAtoms::open ||
|
|
|
|
aAttribute == nsGkAtoms::parentfocused)
|
2011-10-03 11:56:21 +04:00
|
|
|
*aShouldRepaint = true;
|
2005-08-20 11:11:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeGTK::ThemeChanged()
|
|
|
|
{
|
2005-08-20 11:12:57 +04:00
|
|
|
memset(mDisabledWidgetTypes, 0, sizeof(mDisabledWidgetTypes));
|
2017-06-07 08:27:18 +03:00
|
|
|
memset(mSafeWidgetStates, 0, sizeof(mSafeWidgetStates));
|
|
|
|
memset(mBorderCacheValid, 0, sizeof(mBorderCacheValid));
|
2005-08-20 11:11:46 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
NS_IMETHODIMP_(bool)
|
2005-08-20 11:14:04 +04:00
|
|
|
nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
|
2005-08-20 11:12:55 +04:00
|
|
|
nsIFrame* aFrame,
|
2012-08-22 19:56:38 +04:00
|
|
|
uint8_t aWidgetType)
|
2005-08-20 11:11:46 +04:00
|
|
|
{
|
2005-08-20 11:12:57 +04:00
|
|
|
if (IsWidgetTypeDisabled(mDisabledWidgetTypes, aWidgetType))
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2005-08-20 11:12:57 +04:00
|
|
|
|
2005-08-20 11:11:46 +04:00
|
|
|
switch (aWidgetType) {
|
2015-06-08 09:21:42 +03:00
|
|
|
// Combobox dropdowns don't support native theming in vertical mode.
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_MENULIST:
|
|
|
|
case NS_THEME_MENULIST_TEXT:
|
|
|
|
case NS_THEME_MENULIST_TEXTFIELD:
|
2015-06-08 09:21:42 +03:00
|
|
|
if (aFrame && aFrame->GetWritingMode().IsVertical()) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-01-23 09:44:06 +03:00
|
|
|
MOZ_FALLTHROUGH;
|
2015-06-08 09:21:42 +03:00
|
|
|
|
2005-08-20 11:11:46 +04:00
|
|
|
case NS_THEME_BUTTON:
|
2005-08-20 11:14:07 +04:00
|
|
|
case NS_THEME_BUTTON_FOCUS:
|
2005-08-20 11:12:28 +04:00
|
|
|
case NS_THEME_RADIO:
|
2005-08-20 11:11:46 +04:00
|
|
|
case NS_THEME_CHECKBOX:
|
2005-08-20 11:13:48 +04:00
|
|
|
case NS_THEME_TOOLBOX: // N/A
|
|
|
|
case NS_THEME_TOOLBAR:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_TOOLBARBUTTON:
|
|
|
|
case NS_THEME_DUALBUTTON: // so we can override the border with 0
|
|
|
|
case NS_THEME_TOOLBARBUTTON_DROPDOWN:
|
2010-07-27 18:57:47 +04:00
|
|
|
case NS_THEME_BUTTON_ARROW_UP:
|
|
|
|
case NS_THEME_BUTTON_ARROW_DOWN:
|
|
|
|
case NS_THEME_BUTTON_ARROW_NEXT:
|
|
|
|
case NS_THEME_BUTTON_ARROW_PREVIOUS:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SEPARATOR:
|
|
|
|
case NS_THEME_TOOLBARGRIPPER:
|
2005-08-20 11:12:28 +04:00
|
|
|
case NS_THEME_STATUSBAR:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_STATUSBARPANEL:
|
2016-05-19 11:58:00 +03:00
|
|
|
case NS_THEME_RESIZERPANEL:
|
2007-12-11 13:08:35 +03:00
|
|
|
case NS_THEME_RESIZER:
|
2007-06-12 22:29:51 +04:00
|
|
|
case NS_THEME_LISTBOX:
|
2016-05-18 20:29:56 +03:00
|
|
|
// case NS_THEME_LISTITEM:
|
2007-11-07 12:14:58 +03:00
|
|
|
case NS_THEME_TREEVIEW:
|
2016-05-18 20:29:56 +03:00
|
|
|
// case NS_THEME_TREEITEM:
|
|
|
|
case NS_THEME_TREETWISTY:
|
|
|
|
// case NS_THEME_TREELINE:
|
|
|
|
// case NS_THEME_TREEHEADER:
|
|
|
|
case NS_THEME_TREEHEADERCELL:
|
|
|
|
case NS_THEME_TREEHEADERSORTARROW:
|
|
|
|
case NS_THEME_TREETWISTYOPEN:
|
2005-08-20 11:12:29 +04:00
|
|
|
case NS_THEME_PROGRESSBAR:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_PROGRESSCHUNK:
|
2005-08-20 11:12:29 +04:00
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_PROGRESSCHUNK_VERTICAL:
|
2005-08-20 11:12:30 +04:00
|
|
|
case NS_THEME_TAB:
|
2016-05-18 20:29:56 +03:00
|
|
|
// case NS_THEME_TABPANEL:
|
|
|
|
case NS_THEME_TABPANELS:
|
|
|
|
case NS_THEME_TAB_SCROLL_ARROW_BACK:
|
|
|
|
case NS_THEME_TAB_SCROLL_ARROW_FORWARD:
|
2005-08-20 11:12:28 +04:00
|
|
|
case NS_THEME_TOOLTIP:
|
2017-11-29 05:43:13 +03:00
|
|
|
case NS_THEME_INNER_SPIN_BUTTON:
|
2007-12-21 14:30:29 +03:00
|
|
|
case NS_THEME_SPINNER:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SPINNER_UPBUTTON:
|
|
|
|
case NS_THEME_SPINNER_DOWNBUTTON:
|
2007-12-21 14:30:29 +03:00
|
|
|
case NS_THEME_SPINNER_TEXTFIELD:
|
2005-08-20 11:12:30 +04:00
|
|
|
// case NS_THEME_SCROLLBAR: (n/a for gtk)
|
2007-07-14 01:46:28 +04:00
|
|
|
// case NS_THEME_SCROLLBAR_SMALL: (n/a for gtk)
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCROLLBARBUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBARBUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBARBUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBARBUTTON_RIGHT:
|
2015-12-22 07:05:00 +03:00
|
|
|
case NS_THEME_SCROLLBAR_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_VERTICAL:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCROLLBARTRACK_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBARTRACK_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBARTHUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBARTHUMB_VERTICAL:
|
2013-12-09 03:23:28 +04:00
|
|
|
case NS_THEME_NUMBER_INPUT:
|
2005-08-20 11:12:17 +04:00
|
|
|
case NS_THEME_TEXTFIELD:
|
2007-05-07 06:06:58 +04:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2013-03-29 00:25:05 +04:00
|
|
|
case NS_THEME_RANGE:
|
|
|
|
case NS_THEME_RANGE_THUMB:
|
2006-05-30 17:50:48 +04:00
|
|
|
case NS_THEME_SCALE_HORIZONTAL:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCALETHUMB_HORIZONTAL:
|
2006-05-30 17:50:48 +04:00
|
|
|
case NS_THEME_SCALE_VERTICAL:
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_SCALETHUMB_VERTICAL:
|
|
|
|
// case NS_THEME_SCALETHUMBSTART:
|
|
|
|
// case NS_THEME_SCALETHUMBEND:
|
|
|
|
// case NS_THEME_SCALETHUMBTICK:
|
2005-08-20 11:12:28 +04:00
|
|
|
case NS_THEME_CHECKBOX_CONTAINER:
|
|
|
|
case NS_THEME_RADIO_CONTAINER:
|
2005-08-20 11:14:00 +04:00
|
|
|
case NS_THEME_CHECKBOX_LABEL:
|
|
|
|
case NS_THEME_RADIO_LABEL:
|
2005-08-20 11:13:48 +04:00
|
|
|
case NS_THEME_MENUBAR:
|
|
|
|
case NS_THEME_MENUPOPUP:
|
|
|
|
case NS_THEME_MENUITEM:
|
2007-11-29 01:45:21 +03:00
|
|
|
case NS_THEME_MENUARROW:
|
2007-12-11 12:09:09 +03:00
|
|
|
case NS_THEME_MENUSEPARATOR:
|
2005-08-20 11:14:21 +04:00
|
|
|
case NS_THEME_CHECKMENUITEM:
|
|
|
|
case NS_THEME_RADIOMENUITEM:
|
2007-12-21 14:17:01 +03:00
|
|
|
case NS_THEME_SPLITTER:
|
2005-08-20 11:13:45 +04:00
|
|
|
case NS_THEME_WINDOW:
|
|
|
|
case NS_THEME_DIALOG:
|
2018-01-09 13:51:07 +03:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
2015-08-19 22:42:17 +03:00
|
|
|
case NS_THEME_GTK_INFO_BAR:
|
|
|
|
#endif
|
2005-08-20 11:14:11 +04:00
|
|
|
return !IsWidgetStyled(aPresContext, aFrame, aWidgetType);
|
2007-10-26 00:23:13 +04:00
|
|
|
|
2017-09-19 22:22:45 +03:00
|
|
|
case NS_THEME_WINDOW_BUTTON_CLOSE:
|
|
|
|
case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
|
|
|
case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
|
|
|
case NS_THEME_WINDOW_BUTTON_RESTORE:
|
|
|
|
case NS_THEME_WINDOW_TITLEBAR:
|
|
|
|
case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
|
|
|
// GtkHeaderBar is available on GTK 3.10+, which is used for styling
|
|
|
|
// title bars and title buttons.
|
|
|
|
return gtk_check_version(3, 10, 0) == nullptr &&
|
|
|
|
!IsWidgetStyled(aPresContext, aFrame, aWidgetType);
|
|
|
|
|
2016-05-18 20:29:56 +03:00
|
|
|
case NS_THEME_MENULIST_BUTTON:
|
2015-06-08 09:21:42 +03:00
|
|
|
if (aFrame && aFrame->GetWritingMode().IsVertical()) {
|
|
|
|
return false;
|
|
|
|
}
|
2007-10-26 00:23:13 +04:00
|
|
|
// "Native" dropdown buttons cause padding and margin problems, but only
|
|
|
|
// in HTML so allow them in XUL.
|
2009-08-25 00:02:07 +04:00
|
|
|
return (!aFrame || IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) &&
|
2007-10-26 00:23:13 +04:00
|
|
|
!IsWidgetStyled(aPresContext, aFrame, aWidgetType);
|
|
|
|
|
2014-06-14 16:48:08 +04:00
|
|
|
case NS_THEME_FOCUS_OUTLINE:
|
|
|
|
return true;
|
2005-08-20 11:11:46 +04:00
|
|
|
}
|
|
|
|
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2005-08-20 11:11:46 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
NS_IMETHODIMP_(bool)
|
2012-08-22 19:56:38 +04:00
|
|
|
nsNativeThemeGTK::WidgetIsContainer(uint8_t aWidgetType)
|
2005-08-20 11:11:46 +04:00
|
|
|
{
|
|
|
|
// XXXdwh At some point flesh all of this out.
|
2016-05-18 20:29:56 +03:00
|
|
|
if (aWidgetType == NS_THEME_MENULIST_BUTTON ||
|
2008-11-03 16:12:59 +03:00
|
|
|
aWidgetType == NS_THEME_RADIO ||
|
2013-03-29 00:25:05 +04:00
|
|
|
aWidgetType == NS_THEME_RANGE_THUMB ||
|
2008-11-03 16:12:59 +03:00
|
|
|
aWidgetType == NS_THEME_CHECKBOX ||
|
2016-05-18 20:29:56 +03:00
|
|
|
aWidgetType == NS_THEME_TAB_SCROLL_ARROW_BACK ||
|
|
|
|
aWidgetType == NS_THEME_TAB_SCROLL_ARROW_FORWARD ||
|
2010-07-27 18:57:47 +04:00
|
|
|
aWidgetType == NS_THEME_BUTTON_ARROW_UP ||
|
|
|
|
aWidgetType == NS_THEME_BUTTON_ARROW_DOWN ||
|
|
|
|
aWidgetType == NS_THEME_BUTTON_ARROW_NEXT ||
|
|
|
|
aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS)
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
|
|
|
return true;
|
2005-08-20 11:11:46 +04:00
|
|
|
}
|
2007-02-16 04:53:43 +03:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2013-05-14 03:47:03 +04:00
|
|
|
nsNativeThemeGTK::ThemeDrawsFocusForWidget(uint8_t aWidgetType)
|
2007-02-16 04:53:43 +03:00
|
|
|
{
|
2016-05-18 20:29:56 +03:00
|
|
|
if (aWidgetType == NS_THEME_MENULIST ||
|
2017-12-19 13:38:59 +03:00
|
|
|
aWidgetType == NS_THEME_BUTTON ||
|
2016-05-18 20:29:56 +03:00
|
|
|
aWidgetType == NS_THEME_TREEHEADERCELL)
|
2011-10-03 11:56:21 +04:00
|
|
|
return true;
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2007-02-16 04:53:43 +03:00
|
|
|
}
|
2007-05-18 07:04:04 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2007-05-18 07:04:04 +04:00
|
|
|
nsNativeThemeGTK::ThemeNeedsComboboxDropmarker()
|
|
|
|
{
|
2011-10-03 11:56:21 +04:00
|
|
|
return false;
|
2007-05-18 07:04:04 +04:00
|
|
|
}
|
2010-06-18 05:19:21 +04:00
|
|
|
|
|
|
|
nsITheme::Transparency
|
2012-08-22 19:56:38 +04:00
|
|
|
nsNativeThemeGTK::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType)
|
2010-06-18 05:19:21 +04:00
|
|
|
{
|
|
|
|
switch (aWidgetType) {
|
|
|
|
// These widgets always draw a default background.
|
|
|
|
case NS_THEME_MENUPOPUP:
|
|
|
|
case NS_THEME_WINDOW:
|
|
|
|
case NS_THEME_DIALOG:
|
2015-03-18 14:14:00 +03:00
|
|
|
return eOpaque;
|
2015-12-22 07:05:00 +03:00
|
|
|
case NS_THEME_SCROLLBAR_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_HORIZONTAL:
|
2018-01-09 13:51:07 +03:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
2015-07-14 14:35:00 +03:00
|
|
|
// Make scrollbar tracks opaque on the window's scroll frame to prevent
|
|
|
|
// leaf layers from overlapping. See bug 1179780.
|
|
|
|
if (!(CheckBooleanAttr(aFrame, nsGkAtoms::root_) &&
|
|
|
|
aFrame->PresContext()->IsRootContentDocument() &&
|
|
|
|
IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)))
|
|
|
|
return eTransparent;
|
|
|
|
#endif
|
|
|
|
return eOpaque;
|
2015-03-18 14:14:00 +03:00
|
|
|
// Tooltips use gtk_paint_flat_box() on Gtk2
|
|
|
|
// but are shaped on Gtk3
|
2010-08-09 06:17:32 +04:00
|
|
|
case NS_THEME_TOOLTIP:
|
2015-03-18 14:14:00 +03:00
|
|
|
return eTransparent;
|
2010-06-18 05:19:21 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return eUnknownTransparency;
|
|
|
|
}
|