diff --git a/src/applythemes.py b/src/applythemes.py
index 4904896..c3c4a1c 100644
--- a/src/applythemes.py
+++ b/src/applythemes.py
@@ -23,7 +23,7 @@ class BaseApplyThemes:
"""
The base theme applying mechanism: write themes and settings to config files
"""
- def applyThemes(self, props, gtk2Theme, gtk4Theme, kvantumTheme, kvantumThemeFilePath, cssText):
+ def applyThemes(self, props, gtk2Theme, gtk4Theme, kvantumTheme, kvantumThemeFilePath, cssText, gtk4ThemePath):
gtkKeyFile = GLib.KeyFile()
gtkKeyFile.set_string("Settings", "gtk-theme-name", gtk4Theme)
@@ -99,6 +99,9 @@ def applyThemes(self, props, gtk2Theme, gtk4Theme, kvantumTheme, kvantumThemeFil
with open(os.path.join(GLib.get_user_config_dir(), "gtk-3.0", "gtk.css"), "w") as cssFile:
cssFile.write(cssText)
with open(os.path.join(GLib.get_user_config_dir(), "gtk-4.0", "gtk.css"), "w") as cssFile:
+ if gtk4ThemePath is not None:
+ cssFile.write("* {all: unset;}\n")
+ cssFile.write(f'@import url("{gtk4ThemePath}")\n')
cssFile.write(cssText)
class GSettingsApplyThemes(BaseApplyThemes):
diff --git a/src/getavailablethemes.py b/src/getavailablethemes.py
index 5834de0..9fb0861 100644
--- a/src/getavailablethemes.py
+++ b/src/getavailablethemes.py
@@ -1,15 +1,15 @@
# Copyright (C) 2021 Popa Ioan Alexandru
-#
+#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@@ -31,17 +31,16 @@ def uniquifySortedListStore(listStore):
"""
The functions below create Gtk.ListStore's that store themes
for use in SearchableThemeList's and have the following columns:
-1. A str column which holds the display name of the theme
-2. A str column which holds the underlying theme name
-3. (Optional, depends on which kind of themes are used)
- a) A GdkPixbuf.Pixbuf column which holds the theme's preview image
- b) A str column which holds the theme file path (for Kvantum)
+0. A str column which holds the display name of the theme
+1. A str column which holds the underlying theme name
+2. A str column which holds the theme file/folder path (those starting in "//" are fake ones that show a lack of a theme file)
+3. (Optional) A GdkPixbuf.Pixbuf column which holds the theme's preview image
"""
def getAvailableGtk3Themes():
- availableThemes = Gtk.ListStore(str, str, GdkPixbuf.Pixbuf)
+ availableThemes = Gtk.ListStore(str, str, str, GdkPixbuf.Pixbuf)
availableThemes.set_sort_column_id(0, Gtk.SortType.ASCENDING)
- availableThemes.append([" Adwaita", "Adwaita",
+ availableThemes.append([" Adwaita", "Adwaita", "//none",
GdkPixbuf.Pixbuf.new_from_resource(
"/com/github/alex11br/themechanger/adwaita.png"
)
@@ -58,7 +57,7 @@ def getAvailableGtk3Themes():
availableThemes.append([
# we add a space to the beginning of the display name
# to create spacing between the theme preview image and the theme name text
- " "+f, f,
+ " "+f, f, os.path.join(lookupPath, f),
GdkPixbuf.Pixbuf.new_from_file_at_size(
thumbnailFile, 120, 35
) if os.path.isfile(thumbnailFile) else GdkPixbuf.Pixbuf.new_from_resource(
@@ -70,7 +69,7 @@ def getAvailableGtk3Themes():
return uniquifySortedListStore(availableThemes)
def getAvailableIconThemes():
- availableThemes = Gtk.ListStore(str, str, GdkPixbuf.Pixbuf)
+ availableThemes = Gtk.ListStore(str, str, str, GdkPixbuf.Pixbuf)
availableThemes.set_sort_column_id(0, Gtk.SortType.ASCENDING)
lookupPaths = [
os.path.join(GLib.get_user_data_dir(), "icons"),
@@ -89,7 +88,7 @@ def getAvailableIconThemes():
)
if (themeFileParser.get_string("Icon Theme", "Directories")):
availableThemes.append([
- themeFileParser.get_locale_string("Icon Theme", "Name"), f,
+ themeFileParser.get_locale_string("Icon Theme", "Name"), f, os.path.join(lookupPath, f),
iconTheme.load_icon(
iconTheme.get_example_icon_name(),
32, Gtk.IconLookupFlags.FORCE_SIZE
@@ -102,10 +101,10 @@ def getAvailableIconThemes():
return uniquifySortedListStore(availableThemes)
def getAvailableCursorThemes():
- availableThemes = Gtk.ListStore(str, str, GdkPixbuf.Pixbuf)
+ availableThemes = Gtk.ListStore(str, str, str, GdkPixbuf.Pixbuf)
availableThemes.set_sort_column_id(0, Gtk.SortType.ASCENDING)
availableThemes.append([
- "Default cursor", "default",
+ "Default cursor", "default", "//none",
GdkPixbuf.Pixbuf.new_from_resource(
"/com/github/alex11br/themechanger/defaultcursor.png"
)
@@ -125,7 +124,7 @@ def getAvailableCursorThemes():
os.path.join(lookupPath, f, "index.theme"), GLib.KeyFileFlags.NONE
)
availableThemes.append([
- themeFileParser.get_locale_string("Icon Theme", "Name"), f,
+ themeFileParser.get_locale_string("Icon Theme", "Name"), f, os.path.join(lookupPath, f),
pixbufFromXCursor(
cursorPath
) if os.path.isfile(cursorPath) else GdkPixbuf.Pixbuf.new_from_resource(
@@ -139,9 +138,9 @@ def getAvailableCursorThemes():
return uniquifySortedListStore(availableThemes)
def getAvailableGtk4Themes():
- availableThemes = Gtk.ListStore(str, str)
+ availableThemes = Gtk.ListStore(str, str, str)
availableThemes.set_sort_column_id(0, Gtk.SortType.ASCENDING)
- availableThemes.append(["Adwaita", "Adwaita"])
+ availableThemes.append(["Adwaita", "Adwaita", "//none"])
lookupPaths = [
os.path.join(GLib.get_user_data_dir(), "themes"),
os.path.join(GLib.get_home_dir(), ".themes"),
@@ -150,13 +149,13 @@ def getAvailableGtk4Themes():
try:
for f in os.listdir(lookupPath):
if os.path.isfile(os.path.join(lookupPath, f, "gtk-4.0", "gtk.css")):
- availableThemes.append([f, f])
+ availableThemes.append([f, f, os.path.join(lookupPath, f)])
except:
pass
return uniquifySortedListStore(availableThemes)
def getAvailableGtk2Themes():
- availableThemes = Gtk.ListStore(str, str)
+ availableThemes = Gtk.ListStore(str, str, str)
availableThemes.set_sort_column_id(0, Gtk.SortType.ASCENDING)
lookupPaths = [
os.path.join(GLib.get_user_data_dir(), "themes"),
@@ -166,7 +165,7 @@ def getAvailableGtk2Themes():
try:
for f in os.listdir(lookupPath):
if os.path.isfile(os.path.join(lookupPath, f, "gtk-2.0", "gtkrc")):
- availableThemes.append([f, f])
+ availableThemes.append([f, f, os.path.join(lookupPath, f)])
except:
pass
return uniquifySortedListStore(availableThemes)
diff --git a/src/searchablethemelist.py b/src/searchablethemelist.py
index af5114b..6f49a90 100644
--- a/src/searchablethemelist.py
+++ b/src/searchablethemelist.py
@@ -1,15 +1,15 @@
# Copyright (C) 2021 Popa Ioan Alexandru
-#
+#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@@ -38,8 +38,8 @@ def __init__(self, themesTreeViewModel, selectedTheme, onThemeSelectedCallback,
if hasPixbuf:
pixbufCell = Gtk.CellRendererPixbuf()
themeColumn.pack_start(pixbufCell, False)
- themeColumn.add_attribute(pixbufCell, "pixbuf", 2)
-
+ themeColumn.add_attribute(pixbufCell, "pixbuf", 3)
+
nameCell = Gtk.CellRendererText()
themeColumn.pack_start(nameCell, True)
themeColumn.add_attribute(nameCell, "text", 0)
@@ -54,10 +54,12 @@ def selectTheme(self):
self.themesTreeViewModelFiltered.get_path(row.iter),
None, False
)
+ self.selectedThemeRow = row
return
# Maybe the selectedTheme isn't in the model; we'll properly handle this case here
firstRow = self.themesTreeViewModelFiltered[0]
self.selectedTheme = firstRow[1]
+ self.selectedThemeRow = firstRow
self.themesTreeViewSelection.select_iter(firstRow.iter)
self.themesTreeView.scroll_to_point(0, 0)
@@ -70,7 +72,7 @@ def setThemesTreeViewModel(self, themesTreeViewModel):
def setScrolledWindowOverlayScrolling(self, state):
self.themesScrolledWindow.set_overlay_scrolling(state)
-
+
def filterFunc(self, model, treeiter, data):
return self.themesSearchEntry.get_text().lower() in model[treeiter][0].lower()
@@ -83,6 +85,7 @@ def onThemeSelected(self, selection):
if not treeiter:
return
self.selectedTheme = model[treeiter][1]
+ self.selectedThemeRow = model[treeiter]
if self.hasThemeFilePath:
self.onThemeSelectedCallback(self.selectedTheme, model[treeiter][2])
else:
@@ -93,4 +96,3 @@ def onChangeFilter(self, searchentry):
self.themesTreeViewModelFiltered.refilter()
# This handles the case in which the newly filtered model doen't have the selectedTheme anymore
self.selectTheme()
-
\ No newline at end of file
diff --git a/src/window.py b/src/window.py
index d135777..b4b48bb 100644
--- a/src/window.py
+++ b/src/window.py
@@ -246,6 +246,22 @@ def setDefaultCursor(self):
defaultCursor = Gdk.Cursor.new_for_display(self.defaultDisplay, Gdk.CursorType.LEFT_PTR)
self.defaultScreen.get_root_window().set_cursor(defaultCursor)
+ def getGtk4ThemeCssPath(self):
+ if self.anotherGtk4ThemeSwitch.get_active():
+ gtk4ThemeRoot = self.gtk4SearchableThemeList.selectedThemeRow[2]
+ else:
+ gtk4ThemeRoot = self.gtkSearchableThemeList.selectedThemeRow[2]
+
+ if gtk4ThemeRoot[:2] == "//":
+ return None
+
+ gtk4ThemeCssPath = os.path.join(gtk4ThemeRoot, "gtk-4.0", "gtk-dark.css" if self.gtkProps.gtk_application_prefer_dark_theme else "gtk.css")
+ if not os.path.isfile(gtk4ThemeCssPath):
+ gtk4ThemeCssPath = os.path.join(gtk4ThemeRoot, "gtk-4.0", "gtk.css")
+ if not os.path.isfile(gtk4ThemeCssPath):
+ return None
+ return gtk4ThemeCssPath
+
def onGtkThemeChanged(self, themename):
self.onSettingChanged()
@@ -380,7 +396,8 @@ def applySettings(self, *args):
gtk4Theme=self.gtk4ThemeName,
kvantumTheme=self.kvantumThemeName,
kvantumThemeFilePath=self.kvantumThemeFilePath,
- cssText=self.cssTextBuffer.props.text
+ cssText=self.cssTextBuffer.props.text,
+ gtk4ThemePath=self.getGtk4ThemeCssPath()
)
except Exception as err:
showErrorDialog("Error: Could not apply settings", str(err))
diff --git a/src/window.ui b/src/window.ui
index 8c1f486..81ed7e0 100644
--- a/src/window.ui
+++ b/src/window.ui
@@ -248,7 +248,7 @@