LibreOffice Theme Part 2: GTK Color Customization
Most of the UI is covered by themes. The icon theme changes automatically to light or dark based on the window color. Further improvements will be based on the feedback from the users. Change-Id: Ia63ee608fe7870bc7cc86abb892f5fd5d6f1d8ab Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168829 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Reviewed-by: Sahil Gautam <sahil.gautam.extern@allotropia.de> Tested-by: Jenkins
This commit is contained in:
@@ -105,6 +105,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk3,\
|
||||
vcl/unx/gtk3/gtkinst \
|
||||
vcl/unx/gtk3/gtksys \
|
||||
vcl/unx/gtk3/gtkcairo \
|
||||
vcl/unx/gtk3/custom-theme \
|
||||
vcl/unx/gtk3/salnativewidgets-gtk \
|
||||
vcl/unx/gtk3/gtkframe \
|
||||
vcl/unx/gtk3/gtkobject \
|
||||
|
||||
@@ -105,6 +105,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk3_kde5,\
|
||||
vcl/unx/gtk3_kde5/gtk3_kde5_customcellrenderer \
|
||||
vcl/unx/gtk3_kde5/gtk3_kde5_gtkdata \
|
||||
vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst \
|
||||
vcl/unx/gtk3_kde5/gtk3_kde5_custom-theme \
|
||||
vcl/unx/gtk3_kde5/gtk3_kde5_gtksys \
|
||||
vcl/unx/gtk3_kde5/gtk3_kde5_filepicker \
|
||||
vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc \
|
||||
|
||||
@@ -95,6 +95,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk4,\
|
||||
vcl/unx/gtk4/gtkinst \
|
||||
vcl/unx/gtk4/gtksys \
|
||||
vcl/unx/gtk4/gtkcairo \
|
||||
vcl/unx/gtk4/custom-theme \
|
||||
vcl/unx/gtk4/salnativewidgets-gtk \
|
||||
vcl/unx/gtk4/gtkframe \
|
||||
vcl/unx/gtk4/gtkobject \
|
||||
|
||||
@@ -135,6 +135,7 @@ public:
|
||||
#endif
|
||||
private:
|
||||
GtkWidget *mpWindow;
|
||||
static GtkCssProvider *mpCustomThemeProvider;
|
||||
static GtkStyleContext *mpWindowStyle;
|
||||
static GtkStyleContext *mpButtonStyle;
|
||||
static GtkStyleContext *mpLinkButtonStyle;
|
||||
|
||||
@@ -0,0 +1,778 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#include "custom-theme.hxx"
|
||||
#include <vcl/themecolors.hxx>
|
||||
#include <gio/gio.h>
|
||||
#include <unx/gtk/gtkdata.hxx>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
namespace CustomTheme
|
||||
{
|
||||
void LoadColorsFromTheme(StyleSettings& rStyleSet)
|
||||
{
|
||||
const ThemeColors& aThemeColors = ThemeColors::GetThemeColors();
|
||||
|
||||
rStyleSet.SetDialogTextColor(aThemeColors.GetWindowColor());
|
||||
rStyleSet.SetDefaultActionButtonTextColor(aThemeColors.GetWindowTextColor());
|
||||
rStyleSet.SetActionButtonTextColor(aThemeColors.GetButtonTextColor());
|
||||
rStyleSet.SetListBoxWindowTextColor(aThemeColors.GetBaseColor());
|
||||
rStyleSet.SetRadioCheckTextColor(aThemeColors.GetWindowTextColor());
|
||||
rStyleSet.SetGroupTextColor(aThemeColors.GetWindowTextColor());
|
||||
rStyleSet.SetLabelTextColor(aThemeColors.GetWindowTextColor());
|
||||
rStyleSet.SetWindowTextColor(aThemeColors.GetWindowTextColor());
|
||||
rStyleSet.SetFieldTextColor(aThemeColors.GetWindowTextColor());
|
||||
rStyleSet.SetShadowColor(aThemeColors.GetShadeColor());
|
||||
|
||||
rStyleSet.BatchSetBackgrounds(aThemeColors.GetBaseColor());
|
||||
rStyleSet.SetDefaultButtonTextColor(aThemeColors.GetButtonTextColor());
|
||||
rStyleSet.SetDefaultButtonRolloverTextColor(aThemeColors.GetButtonTextColor());
|
||||
rStyleSet.SetDefaultButtonPressedRolloverTextColor(aThemeColors.GetFaceColor());
|
||||
rStyleSet.SetButtonRolloverTextColor(aThemeColors.GetButtonTextColor());
|
||||
rStyleSet.SetDefaultActionButtonRolloverTextColor(aThemeColors.GetFaceColor());
|
||||
rStyleSet.SetDefaultActionButtonPressedRolloverTextColor(aThemeColors.GetFaceColor());
|
||||
rStyleSet.SetActionButtonRolloverTextColor(aThemeColors.GetFaceColor());
|
||||
rStyleSet.SetActionButtonPressedRolloverTextColor(aThemeColors.GetFaceColor());
|
||||
rStyleSet.SetFlatButtonTextColor(aThemeColors.GetFaceColor());
|
||||
rStyleSet.SetFlatButtonPressedRolloverTextColor(aThemeColors.GetFaceColor());
|
||||
rStyleSet.SetFlatButtonRolloverTextColor(aThemeColors.GetFaceColor());
|
||||
rStyleSet.SetFieldRolloverTextColor(aThemeColors.GetFaceColor());
|
||||
|
||||
// Some colors like ButtonRolloverTextColor are present in the StyleSettings but
|
||||
// not in ThemeColors, hence cannot be customized yet. These will be added to
|
||||
// ThemeColors as the themeing system evolves. Leaving as commented for now.
|
||||
|
||||
// rStyleSet.SetButtonRolloverTextColor(Color(0));
|
||||
// rStyleSet.SetButtonPressedRolloverTextColor(Color(0));
|
||||
// rStyleSet.SetHelpColor(Color(0));
|
||||
// rStyleSet.SetHelpTextColor(Color(0));
|
||||
|
||||
rStyleSet.SetAccentColor(aThemeColors.GetAccentColor());
|
||||
rStyleSet.SetHighlightColor(aThemeColors.GetAccentColor());
|
||||
rStyleSet.SetHighlightTextColor(aThemeColors.GetActiveTextColor());
|
||||
rStyleSet.SetListBoxWindowHighlightColor(aThemeColors.GetActiveColor());
|
||||
rStyleSet.SetListBoxWindowHighlightTextColor(aThemeColors.GetActiveTextColor());
|
||||
rStyleSet.SetActiveColor(aThemeColors.GetActiveColor());
|
||||
rStyleSet.SetActiveTextColor(aThemeColors.GetActiveTextColor());
|
||||
|
||||
rStyleSet.SetFieldColor(aThemeColors.GetFieldColor());
|
||||
|
||||
rStyleSet.SetWindowColor(aThemeColors.GetWindowColor());
|
||||
rStyleSet.SetListBoxWindowBackgroundColor(aThemeColors.GetWindowColor());
|
||||
|
||||
rStyleSet.SetActiveTabColor(aThemeColors.GetActiveColor());
|
||||
rStyleSet.SetInactiveTabColor(aThemeColors.GetInactiveColor());
|
||||
|
||||
rStyleSet.SetMenuColor(aThemeColors.GetMenuColor());
|
||||
rStyleSet.SetMenuBarColor(aThemeColors.GetMenuBarColor());
|
||||
rStyleSet.SetMenuBarRolloverColor(aThemeColors.GetMenuBarHighlightColor());
|
||||
rStyleSet.SetMenuBarTextColor(aThemeColors.GetMenuBarTextColor());
|
||||
rStyleSet.SetMenuBarRolloverTextColor(aThemeColors.GetMenuBarHighlightTextColor());
|
||||
rStyleSet.SetMenuBarHighlightTextColor(aThemeColors.GetMenuHighlightTextColor());
|
||||
rStyleSet.SetMenuTextColor(aThemeColors.GetMenuTextColor());
|
||||
rStyleSet.SetMenuHighlightColor(aThemeColors.GetMenuHighlightColor());
|
||||
rStyleSet.SetMenuHighlightTextColor(aThemeColors.GetMenuHighlightTextColor());
|
||||
|
||||
rStyleSet.SetLinkColor(aThemeColors.GetActiveColor());
|
||||
|
||||
Color aVisitedLinkColor = aThemeColors.GetActiveColor();
|
||||
aVisitedLinkColor.Merge(aThemeColors.GetWindowColor(), 100);
|
||||
rStyleSet.SetVisitedLinkColor(aVisitedLinkColor);
|
||||
rStyleSet.SetTabTextColor(aThemeColors.GetMenuBarTextColor());
|
||||
rStyleSet.SetToolTextColor(aThemeColors.GetWindowTextColor());
|
||||
rStyleSet.SetTabRolloverTextColor(aThemeColors.GetMenuBarHighlightTextColor());
|
||||
}
|
||||
|
||||
#if GTK_CHECK_VERSION(4, 0, 0)
|
||||
void ApplyCustomTheme(GdkDisplay* pGdkDisplay, GtkCssProvider** pCustomThemeProvider)
|
||||
#else
|
||||
void ApplyCustomTheme(GdkScreen* pScreen, GtkCssProvider** pCustomThemeProvider)
|
||||
#endif
|
||||
{
|
||||
if (!ThemeColors::IsThemeLoaded()
|
||||
|| ThemeColors::IsAutomaticTheme(ThemeColors::GetThemeColors().GetThemeName()))
|
||||
return;
|
||||
|
||||
if ((*pCustomThemeProvider) == nullptr)
|
||||
{
|
||||
(*pCustomThemeProvider) = gtk_css_provider_new();
|
||||
OString aStyleString = CreateStyleString();
|
||||
|
||||
css_provider_load_from_data(*pCustomThemeProvider, aStyleString.getStr(),
|
||||
aStyleString.getLength());
|
||||
|
||||
#if GTK_CHECK_VERSION(4, 0, 0)
|
||||
gtk_style_context_add_provider_for_display(pGdkDisplay,
|
||||
GTK_STYLE_PROVIDER(*pCustomThemeProvider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
#else
|
||||
gtk_style_context_add_provider_for_screen(
|
||||
pScreen, GTK_STYLE_PROVIDER(*pCustomThemeProvider), GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
OString CreateStyleString()
|
||||
{
|
||||
const ThemeColors& aThemeColors = ThemeColors::GetThemeColors();
|
||||
|
||||
Color aSpinBack = aThemeColors.GetBaseColor();
|
||||
aSpinBack.SetAlpha(20);
|
||||
|
||||
Color aPressedColor = ThemeColors::GetThemeColors().GetWindowColor();
|
||||
if (aPressedColor.IsDark())
|
||||
aPressedColor.IncreaseLuminance(30);
|
||||
else
|
||||
aPressedColor.DecreaseLuminance(30);
|
||||
|
||||
OUString aStr =
|
||||
/***************
|
||||
* Base States *
|
||||
***************/
|
||||
".background {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetWindowColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
".view {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetBaseColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"textview text {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetBaseColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
/*********
|
||||
* Links *
|
||||
*********/
|
||||
"*:link,"
|
||||
"link {"
|
||||
" color: #"
|
||||
+ aThemeColors.GetActiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"*:visited {"
|
||||
" color: #"
|
||||
+ aThemeColors.GetBaseColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
/************
|
||||
* Toolbars *
|
||||
************/
|
||||
"toolbar {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetWindowColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
".toolbar {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetWindowColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
/**************
|
||||
* Tree Views *
|
||||
**************/
|
||||
"treeview.view:selected {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetAccentColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHEXString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"treeview.view:drop(active) {"
|
||||
" border-style: solid none;"
|
||||
" border-color: alpha(currentColor, 0.08);"
|
||||
"}"
|
||||
|
||||
"treeview.view.expander {"
|
||||
" color: #"
|
||||
+ aThemeColors.GetFaceColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"treeview.view.expander:hover,"
|
||||
"treeview.view.expander:active {"
|
||||
" color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"treeview.view.expander:disabled {"
|
||||
" color: #"
|
||||
+ aThemeColors.GetInactiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
// this part is still left
|
||||
"treeview.view.trough {"
|
||||
" background-color: rgba(239, 241, 245, 0.12);"
|
||||
"}"
|
||||
|
||||
"treeview.view header button:not(:focus):not(:hover):not(:active) {"
|
||||
" color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"treeview.view header button,"
|
||||
"treeview.view header button:disabled {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetInactiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"treeview.view header button:last-child {"
|
||||
" border-right-style: none;"
|
||||
"}"
|
||||
|
||||
"treeview.view button.dnd,"
|
||||
"treeview.view header.button.dnd {"
|
||||
" background-color: #ff0000;"
|
||||
" color: #89b4fa;"
|
||||
"}"
|
||||
|
||||
/*********
|
||||
* Menus *
|
||||
*********/
|
||||
"menubar,"
|
||||
".menubar {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetMenuBarColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"menubar > menuitem,"
|
||||
".menubar > menuitem {"
|
||||
" color: #"
|
||||
+ aThemeColors.GetMenuBarTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"menubar > menuitem:hover,"
|
||||
".menubar > menuitem:hover {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetMenuBarHighlightColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetMenuBarHighlightTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"menubar > menuitem:disabled,"
|
||||
".menubar > menuitem:disabled {"
|
||||
" color: #"
|
||||
+ aThemeColors.GetInactiveTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"menubar > menuitem label:disabled,"
|
||||
".menubar > menuitem label:disabled {"
|
||||
" color: inherit;"
|
||||
"}"
|
||||
|
||||
"menu {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetMenuColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" border: 1px solid #"
|
||||
+ aThemeColors.GetMenuBorderColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"menu menuitem {"
|
||||
" color: #"
|
||||
+ aThemeColors.GetMenuTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"menu menuitem:hover {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetMenuHighlightColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetMenuHighlightTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"menu menuitem:active {"
|
||||
" background-color: alpha(currentColor, 0.12);"
|
||||
"}"
|
||||
|
||||
"menu menuitem:disabled {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetMenuColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetDisabledTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" border-left: 1px solid #"
|
||||
+ aThemeColors.GetMenuBorderColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" border-right: 1px solid #"
|
||||
+ aThemeColors.GetMenuBorderColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"menu menuitem accelerator {"
|
||||
" color: rgba(239, 241, 245, 0.7);" // ???
|
||||
"}"
|
||||
|
||||
"menu menuitem:disabled accelerator {"
|
||||
" color: rgba(239, 241, 245, 0.32);" // ???
|
||||
"}"
|
||||
|
||||
"menu menuitem label:dir(rtl),"
|
||||
"menu menuitem label:dir(ltr) {"
|
||||
" color: inherit;"
|
||||
"}"
|
||||
|
||||
/*************
|
||||
* Notebooks *
|
||||
*************/
|
||||
|
||||
"tabbox > tab:hover,"
|
||||
"notebook > header tab:hover {"
|
||||
" background-color: #"
|
||||
+ aPressedColor.AsRGBHexString()
|
||||
+ ";"
|
||||
" border: 1px solid #"
|
||||
+ aThemeColors.GetSeparatorColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
""
|
||||
"tabbox > tab:checked, notebook > header tab:checked {"
|
||||
" background-color: #"
|
||||
+ aPressedColor.AsRGBHexString()
|
||||
+ ";"
|
||||
" border: 1px solid #"
|
||||
+ aThemeColors.GetSeparatorColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
""
|
||||
"notebook {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetWindowColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
""
|
||||
"notebook > header {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetBaseColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" border-color: #"
|
||||
+ aThemeColors.GetBaseColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
""
|
||||
"notebook > stack:not(:only-child) {"
|
||||
" background-color: transparent;"
|
||||
"}"
|
||||
|
||||
/************
|
||||
* Scrollbar*
|
||||
*************/
|
||||
|
||||
"scrollbar {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetBaseColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"scrollbar slider {"
|
||||
" border: 4px solid transparent;"
|
||||
" background-clip: padding-box;"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetWindowColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"scrollbar slider:hover {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"scrollbar slider:active {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"scrollbar slider:disabled {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetInactiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"scrollbar.overlay-indicator:not(.dragging):not(.hovering) {"
|
||||
" background-color: transparent;"
|
||||
"}"
|
||||
|
||||
/*****************
|
||||
* Check n Radio *
|
||||
* ***************/
|
||||
|
||||
"check:disabled,"
|
||||
"radio:disabled {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetInactiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"check:checked,"
|
||||
"check:indeterminate,"
|
||||
"radio:checked,"
|
||||
"radio:indeterminate {"
|
||||
" color: rgba(17, 17, 27, 0.87);"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetActiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"check:checked:hover,"
|
||||
"check:indeterminate:hover,"
|
||||
"radio:checked:hover,"
|
||||
"radio:indeterminate:hover {"
|
||||
" box-shadow: 0 0 0 6px rgba(137, 180, 250, 0.15);"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"check:checked:active,"
|
||||
"check:indeterminate:active,"
|
||||
"radio:checked:active,"
|
||||
"radio:indeterminate:active {"
|
||||
" box-shadow: 0 0 0 6px rgba(137, 180, 250, 0.2);"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetActiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"check:checked:disabled,"
|
||||
"check:indeterminate:disabled,"
|
||||
"radio:checked:disabled,"
|
||||
"radio:indeterminate:disabled {"
|
||||
" color: rgba(17, 17, 27, 0.38);"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetInactiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
/***************
|
||||
* Progressbar *
|
||||
* *************/
|
||||
|
||||
"progressbar {"
|
||||
" color: rgba(239, 241, 245, 0.7);"
|
||||
" font-size: smaller;"
|
||||
"}"
|
||||
|
||||
"progressbar trough {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetBaseColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"progressbar progress {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetActiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"frame > border,"
|
||||
".frame {"
|
||||
" border-radius: 0;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
|
||||
".frame.view {"
|
||||
" border-radius: 6px;"
|
||||
"}"
|
||||
|
||||
".frame.flat {"
|
||||
" border-style: none;"
|
||||
"}"
|
||||
|
||||
"separator {"
|
||||
" min-width: 1px;"
|
||||
" min-height: 1px;"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetBaseColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
/***********
|
||||
* Buttons *
|
||||
***********/
|
||||
|
||||
".toolbar button:checked,"
|
||||
"#buttonbox_frame button:checked,"
|
||||
"layouttabbar button:checked,"
|
||||
"messagedialog .dialog-action-box button:checked,"
|
||||
"messagedialog .dialog-action-box .linked:not(.vertical) > button:checked,"
|
||||
"popover.background.menu button:checked,"
|
||||
"popover.background button.model:checked,"
|
||||
"headerbar button:checked:not(.suggested-action):not(.destructive-action),"
|
||||
"toolbar button:checked,"
|
||||
"combobox > .linked:not(.vertical) > button:checked:not(:only-child),"
|
||||
"button.flat:checked,"
|
||||
"button.flat:checked:hover {"
|
||||
" background-color: alpha(#"
|
||||
+ aThemeColors.GetButtonColor().AsRGBHexString()
|
||||
+ ", 0.1);"
|
||||
" color: #"
|
||||
+ aThemeColors.GetButtonTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
""
|
||||
"button:active {"
|
||||
" background-color: #"
|
||||
+ aPressedColor.AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetButtonTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"button:disabled {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetInactiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetInactiveTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" border: 1px solid #"
|
||||
+ aThemeColors.GetInactiveBorderColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
/*****************
|
||||
* GtkSpinButton *
|
||||
*****************/
|
||||
|
||||
"spinbutton > entry,"
|
||||
"spinbutton > entry:focus,"
|
||||
"spinbutton > entry:disabled,"
|
||||
".background:not(.csd) spinbutton > entry,"
|
||||
".background:not(.csd) spinbutton > entry:focus,"
|
||||
".background:not(.csd) spinbutton > entry:disabled {"
|
||||
" border: none;"
|
||||
" box-shadow: none;"
|
||||
" background-color: transparent;"
|
||||
"}"
|
||||
|
||||
"spinbutton > button {"
|
||||
" border: solid 6px transparent;"
|
||||
"}"
|
||||
|
||||
"spinbutton > button:focus:not(:hover):not(:active):not(:disabled) {"
|
||||
" box-shadow: inset 0 0 0 9999px transparent;"
|
||||
" color: #"
|
||||
+ aThemeColors.GetButtonTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"spinbutton,"
|
||||
"entry {"
|
||||
" background-color: #"
|
||||
+ aSpinBack.AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetButtonTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"spinbutton:focus,"
|
||||
"entry:focus {"
|
||||
" background-color: #"
|
||||
+ aSpinBack.AsRGBHexString()
|
||||
+ ";"
|
||||
" box-shadow: inset 0 0 0 2px #"
|
||||
+ aThemeColors.GetActiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"spinbutton:disabled,"
|
||||
"entry:disabled {"
|
||||
" box-shadow: inset 0 0 0 2px transparent;"
|
||||
" background-color: #"
|
||||
+ aSpinBack.AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetInactiveTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
/**************
|
||||
* ComboBoxes *
|
||||
**************/
|
||||
"button.combo:only-child {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetButtonColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetButtonTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"button.combo:only-child:checked {"
|
||||
" background-color: #"
|
||||
+ aPressedColor.AsRGBHexString()
|
||||
+ ";"
|
||||
" box-shadow: 0 0 0 2px #"
|
||||
+ aThemeColors.GetButtonColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"button.combo:only-child:disabled {"
|
||||
" box-shadow: 0 0 0 2px transparent;"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetInactiveColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetInactiveTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
// this one still needs some digging
|
||||
"button.small-button, toolbar.small-button button, box.small-button button {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetMenuBarColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
// for the file picker dialog
|
||||
"list {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetWindowColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"treeview.view header button {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetWindowColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
/************
|
||||
* Tooltips *
|
||||
************/
|
||||
"tooltip {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetBaseColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"tooltip * {"
|
||||
" color: #"
|
||||
+ aThemeColors.GetWindowTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"actionbar > revealer > box .linked > "
|
||||
"button:not(.suggested-action):not(.destructive-action), button {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetButtonColor().AsRGBHexString()
|
||||
+ ";"
|
||||
" background-image: radial-gradient(circle, transparent 10%, transparent 0%);"
|
||||
" color: #"
|
||||
+ aThemeColors.GetButtonTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
""
|
||||
""
|
||||
"actionbar > revealer > box .linked > "
|
||||
"button:checked:not(.suggested-action):not(.destructive-action), button:checked {"
|
||||
" background-color: #"
|
||||
+ aPressedColor.AsRGBHexString()
|
||||
+ ";"
|
||||
" color: #"
|
||||
+ aThemeColors.GetButtonTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
"tabbox>tab button,"
|
||||
"treeview.view header button button.circular,"
|
||||
"scrollbar button,"
|
||||
"notebook>header>tabs>arrow,"
|
||||
"spinbutton>button,"
|
||||
"toolbar button,"
|
||||
"button.flat {"
|
||||
" background-color: transparent;"
|
||||
"}"
|
||||
|
||||
"button.flat:hover {"
|
||||
" background-color: #"
|
||||
+ aPressedColor.AsRGBHexString()
|
||||
+ ";"
|
||||
" border: 1px solid #"
|
||||
+ aThemeColors.GetSeparatorColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
// this alone won't do
|
||||
".toolbar button:checked,"
|
||||
".toolbar button:hover,"
|
||||
"toolbar button:checked,"
|
||||
"toolbar button:hover,"
|
||||
"button.flat:checked,"
|
||||
"button.label-button,"
|
||||
"button.flat:checked:hover {"
|
||||
" background-color: #"
|
||||
+ aPressedColor.AsRGBHexString()
|
||||
+ ";"
|
||||
" text-shadow: none;"
|
||||
"}"
|
||||
|
||||
"button.destructive-action:not(:disabled) {"
|
||||
" background-color: #f38ba8;"
|
||||
" color: #"
|
||||
+ aThemeColors.GetButtonTextColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}"
|
||||
|
||||
".view:selected {"
|
||||
" background-color: #"
|
||||
+ aThemeColors.GetAccentColor().AsRGBHexString()
|
||||
+ ";"
|
||||
"}";
|
||||
|
||||
return OUStringToOString(aStr, RTL_TEXTENCODING_UTF8);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* 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/.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtkcssprovider.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <vcl/settings.hxx>
|
||||
|
||||
namespace CustomTheme
|
||||
{
|
||||
#if GTK_CHECK_VERSION(4, 0, 0)
|
||||
void ApplyCustomTheme(GdkDisplay* pGdkDisplay, GtkCssProvider** pCustomThemeProvider);
|
||||
#else
|
||||
void ApplyCustomTheme(GdkScreen* pScreen, GtkCssProvider** pCustomThemeProvider);
|
||||
#endif
|
||||
|
||||
OString CreateStyleString();
|
||||
void LoadColorsFromTheme(StyleSettings& rStyleSet);
|
||||
}
|
||||
@@ -24,9 +24,13 @@
|
||||
#include <unx/fontmanager.hxx>
|
||||
#include <o3tl/string_view.hxx>
|
||||
|
||||
#include <IconThemeSelector.hxx>
|
||||
#include "custom-theme.hxx"
|
||||
#include <vcl/themecolors.hxx>
|
||||
#include "gtkcairo.hxx"
|
||||
#include <optional>
|
||||
|
||||
GtkCssProvider* GtkSalGraphics::mpCustomThemeProvider = nullptr;
|
||||
GtkStyleContext* GtkSalGraphics::mpWindowStyle = nullptr;
|
||||
GtkStyleContext* GtkSalGraphics::mpButtonStyle = nullptr;
|
||||
GtkStyleContext* GtkSalGraphics::mpLinkButtonStyle = nullptr;
|
||||
@@ -2308,6 +2312,12 @@ bool GtkSalGraphics::updateSettings(AllSettings& rSettings)
|
||||
GtkSettings* pSettings = gtk_widget_get_settings(pTopLevel);
|
||||
StyleSettings aStyleSet = rSettings.GetStyleSettings();
|
||||
|
||||
#if GTK_CHECK_VERSION(4, 0, 0)
|
||||
CustomTheme::ApplyCustomTheme(gtk_widget_get_display(pTopLevel), &mpCustomThemeProvider);
|
||||
#else
|
||||
CustomTheme::ApplyCustomTheme(gtk_widget_get_screen(pTopLevel), &mpCustomThemeProvider);
|
||||
#endif
|
||||
|
||||
// text colors
|
||||
GdkRGBA text_color;
|
||||
style_context_set_state(pStyle, GTK_STATE_FLAG_NORMAL);
|
||||
@@ -2660,14 +2670,22 @@ bool GtkSalGraphics::updateSettings(AllSettings& rSettings)
|
||||
aStyleSet.SetMinThumbSize(min_slider_length);
|
||||
|
||||
// preferred icon style
|
||||
gchar* pIconThemeName = nullptr;
|
||||
gboolean bDarkIconTheme = false;
|
||||
g_object_get(pSettings, "gtk-icon-theme-name", &pIconThemeName,
|
||||
"gtk-application-prefer-dark-theme", &bDarkIconTheme,
|
||||
nullptr );
|
||||
OUString sIconThemeName(OUString::createFromAscii(pIconThemeName));
|
||||
aStyleSet.SetPreferredIconTheme(sIconThemeName, bDarkIconTheme);
|
||||
g_free( pIconThemeName );
|
||||
if (!ThemeColors::IsThemeLoaded())
|
||||
{
|
||||
gchar* pIconThemeName = nullptr;
|
||||
gboolean bDarkIconTheme = false;
|
||||
g_object_get(pSettings, "gtk-icon-theme-name", &pIconThemeName,
|
||||
"gtk-application-prefer-dark-theme", &bDarkIconTheme,
|
||||
nullptr );
|
||||
OUString sIconThemeName(OUString::createFromAscii(pIconThemeName));
|
||||
aStyleSet.SetPreferredIconTheme(sIconThemeName, bDarkIconTheme);
|
||||
g_free( pIconThemeName );
|
||||
}
|
||||
else
|
||||
{
|
||||
aStyleSet.SetPreferredIconTheme(vcl::IconThemeSelector::GetIconThemeForDesktopEnvironment(
|
||||
Application::GetDesktopEnvironment(), ThemeColors::GetThemeColors().GetWindowColor().IsDark()));
|
||||
}
|
||||
|
||||
aStyleSet.SetToolbarIconSize( ToolbarIconSize::Large );
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#include "../gtk3/custom-theme.cxx"
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
@@ -0,0 +1,12 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#include "../gtk3/custom-theme.hxx"
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
@@ -0,0 +1,12 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#include "../gtk3/custom-theme.cxx"
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
@@ -0,0 +1,12 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#include "../gtk3/custom-theme.hxx"
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
Reference in New Issue
Block a user