Fluxbox Themes matching GTK themes

Help for MX Fluxbox
When asking for help, use Quick System Info from MX Tools. It will be properly formatted using the following steps.
1. Click on Quick System Info in MX Tools
2. Right click in your post and paste.
Message
Author
orcrist
Posts: 60
Joined: Sun Apr 15, 2018 3:43 am

Re: Fluxbox Themes matching GTK themes

#41 Post by orcrist »

purplemoon wrote: Sat Nov 20, 2021 5:41 pm
Jerry3904 wrote: Tue Nov 09, 2021 5:51 pm Nice progress!
Thanks a lot Jerry! :happy: But there is always some room for improvement...
... so while working on my winter theme I ended up with this...
FB-Fluent.tar.gz
[updated 2021-12-11 v0.1 --> v0.2a --> match GTK3 menus; changed toolbar color ]

It is still a work in progress though. The tiling buttons should be added to the 'init' file in order to be displayed on the titlebar. 'Fluent-grey' GTK theme and 'Reversal-grey-dark' icons are used as a starting point (details in the 'README' file).

It would be nice to have some feedback (on this theme and the previous ones) in order to point issues that I am not aware of.

Here are some [updated 2021-12-11] screenshots anyway (note: this is still MX-FB 19).

sc_fluent_02.jpgsc_fluent_04.jpg

Sidenote: I have become aware that re-using the original theme names may raise some issues, so, I am considering renaming some of them.
Wonderful theme @purplemoon, thank you very much. Nice matching rofi theme too.

purplemoon
Posts: 41
Joined: Fri Apr 16, 2021 6:10 pm

Re: Fluxbox Themes matching GTK themes

#42 Post by purplemoon »

@orcrist Thank you! However, some improvements are needed. I will try to make time to review / update themes.

Here are FB-Arc-Blackest and FB-Flat-Remix-Red-Darkest updated:
FB-Arc-Blackest.tar.gz
FB-Flat-Remix-Red-Darkest.tar.gz
A screenshot featuring Fluxbox default panel and FBpanel:
sc_fb-arc-blackest.jpeg
And if anyone is interested, the matching Rofi themes
rofi_themes.tar.gz
If you want to see more, these are displayed here:
https://www.youtube.com/watch?v=m0hwdUgjwlA
and here:
https://www.youtube.com/watch?v=UFD_VAKQxD4
You do not have the required permissions to view the files attached to this post.

User avatar
Jerry3904
Administrator
Posts: 23047
Joined: Wed Jul 19, 2006 6:13 am

Re: Fluxbox Themes matching GTK themes

#43 Post by Jerry3904 »

Looking good!

Now that we have released MX-Look it is much easier for users to save and re-use and a certain "look" (selected theme elements) in MX Fluxbox.
Production: 5.10, MX-23 Xfce, AMD FX-4130 Quad-Core, GeForce GT 630/PCIe/SSE2, 16 GB, SSD 120 GB, Data 1TB
Personal: Lenovo X1 Carbon with MX-23 Fluxbox
Other: Raspberry Pi 5 with MX-23 Xfce Raspberry Pi Respin

purplemoon
Posts: 41
Joined: Fri Apr 16, 2021 6:10 pm

Re: Fluxbox Themes matching GTK themes

#44 Post by purplemoon »

@Jerry3904 I have watched your video and will try it soon to change to an autumn theme...

In the meantime, I am working on a script for changing colors to match the current gtk theme (only Rofi for now). It is a very dirty code as I am learning on the way, but it works. The idea (for now) is to use a Rofi theme template [fb_BnW.rasi] and create a new theme [gtk_default.rasi] that is already selected in the rofi theme selector. It does not work with all gtk themes, but should be ok with the default selection on the iso.

Here is the test template to copy into ~/.config/rofi/themes

Code: Select all

/**
 * ROFI Color theme
 */
* {
    //
    // BnW (BLACK & WHITE) style
    //
    // Colors
    
    bg-inpt: #1c1c1c;	// inputbar background
    fg-inpt: #ebebeb;	// inputbar text
        
    bg-win: #1c1c1c;		// window background
    fg-nor: #ebebeb;	// text normal unselected
    
    bg-sel: #ebebeb;	// item selected background
    fg-sel: #1c1c1c;		// text normal selected
    
    
    background-color: @bg-win;

    font: "Noto Sans Mono CJK KR Regular 12";
    //
    border: 0;
    margin: 0;
    padding: 0;
    spacing: 0;
}
window {
    location: center;
    anchor:   center;
    width: 40%;
}

element {
	padding: 12;
	text-color: @fg-nor;
}

element selected {
	background-color: @bg-sel;
	text-color: @fg-sel;
}

element-text {
	background-color: inherit;
	text-color: inherit;
	vertical-align: 0.5;
}

element-icon {
	size: 30;
}

entry {
	background-color: @bg-inpt;
	padding: 12;
	text-color: @fg-inpt;
}

inputbar {
	children: [prompt, entry];
}

listview {
	background-color: @bg-win;
	columns: 1;
	lines: 10;
}

mainbox {
    background-color: @bg-win;
    children: [ inputbar, message, listview ];
}

prompt {
	background-color: @bg-inpt;
	enabled: true;
	padding: 12 0 0 12;
	text-color: @fg-inpt;
}


And the very dirty script:

Code: Select all

import os
import sys
from tkinter import *
import time
from os.path import exists
from os.path import expanduser
from pathlib import Path

import shutil
import subprocess



# Variables
home = ""
gtk_style_name = ""
gtk_style_name_path = ""


# Identify user name / home

def find_home_user():
    global home
    home = expanduser("~")
    print(home)


# Identify current gtk theme name in ~/.config/gtk-3.0/settings.ini

def find_curr_gtk_style_name():
    global gtk_style_name_path
    global gtk_style_name

    gtk_style_name_path = os.path.join(home, ".config/gtk-3.0/settings.ini")
    #print(gtk_style_name_path+"eee")
    if os.path.exists(gtk_style_name_path):
        print("File located at: " + gtk_style_name_path)
        try:
            ofi = open(gtk_style_name_path, "r")
            t=0
            while t != "":
                t = ofi.readline()
                #if "gtk-theme-name" in t:
                    #print("line located")
                    #break
                if "gtk-theme-name" in t:
                    cut = t.find("=") + 1
                    gtk_style_name = t[cut:-1]
                    print("Current GTK theme in use: " + gtk_style_name)
                    break

            ofi.close()

        except FileNotFoundError:
            print("File not found :(")

    else:
        print("File not found")


# Locate current GTK theme in /usr/share/themes OR /home/[user]/.themes

def locate_curr_gtk_file ():
    global gtk_style_path_1
    global gtk_style_path_2
    global curr_gtk_style_path
    
    gtk_style_path_1 = home + "/.themes/" + gtk_style_name + "/gtk-2.0/gtkrc"
#    gtk_style_path_1 = os.path.join(home, "/.themes/", gtk_style_name, "/gtk-2.0/gtkrc")
    gtk_style_path_2 = "/usr/share/themes/" + gtk_style_name + "/gtk-2.0/gtkrc"
#    gtk_style_path_1 = os.path.join("/usr/share/themes/", gtk_style_name, "/gtk-2.0/gtkrc")

    if os.path.exists(gtk_style_path_2):
        print("File located at:")
        curr_gtk_style_path = gtk_style_path_2
        print(curr_gtk_style_path)

    elif os.path.exists(gtk_style_path_1):
        print("File located at:")
        curr_gtk_style_path = gtk_style_path_1
        print(curr_gtk_style_path)
    else:
        print("File not found")


# retrieve data (colors) from gtk file

def get_gtk_colors():

    global col_item
    global col_lst

    col_item = ""
    col_lst = []
    d = 0

    with open(curr_gtk_style_path, "r") as ofi:

        while d != "":
#        for lines in curr_gtk_style_path:
            d = ofi.readline()

            if "gtk-color-scheme" in d:
                beg = d.find("\"")
                md = d.find("\\")

                beg = beg+1

                if "\\" in d:

                    md_b = md +2

                    #print(beg)
                    #print(md)
                    print(d[beg:md])
                    col_item = d[beg:md]
                    col_lst.append(col_item)
                    print(d[md_b:-2])
                    col_item = d[md_b:-2]
                    col_lst.append(col_item)

                else:
                    #print(beg)
                    #print(d[beg:-2])
                    col_item = d[beg:-2]
                    col_lst.append(col_item)

        print(col_lst)


####### added stuff from test_004.py


col_dict = {}
cpt = 0
gtk_col_dict = {}

# parse gtk data

def parse():
    
    global col_lst
    global gtk_col_dict

    for item in col_lst:
    #    print(item)
        cut = item.find(":")
        cut2 = cut+1
    #    print(item[:cut] +" --> "+ item[cut2:])
        gtk_col_dict.update({item[:cut]: item[cut2:]})


#parse()

print(gtk_col_dict.keys())
print("done!")

# open Rofi theme path

# Identify rofi theme template & rofi default gtk theme

def locate_rofi_themes():
    home = expanduser("~")
#    rofi_th_src = ""
#    rofi_th_dest = ""
    print(home)
    global rofi_th_src
    global rofi_th_dest
    rofi_th_src = home + "/" + ".config/rofi/themes/fb_BnW.rasi"
    rofi_th_dest = home + "/" + ".config/rofi/themes/gtk_default.rasi"


    print(rofi_th_src)
    print(rofi_th_dest)

locate_rofi_themes()
   

def copy_to_default(source, destination):
    
    global rofi_th_src
    global rofi_th_dest
#    with open(rofi_th_src, "r") as ofi:
#        line = "1"
#        while line != "":
#            line = ofi.readline()
#            print(line)

    fs = open(rofi_th_src, "r")
    fd = open(rofi_th_dest, "w")
    while 1:
        line = fs.readline()
        if line == "":
            break
        if "bg-inpt: " in line:
            if "wm_color" in gtk_col_dict:
                line = "bg-inpt: " + gtk_col_dict["wm_color"]+ ";\n"
            elif "titlebar_bg_color" in gtk_col_dict:
                line = "bg-inpt: " + gtk_col_dict["titlebar_bg_color"]+ ";\n"
            elif "menubar_bg" in gtk_col_dict:
                line = "bg-inpt: " + gtk_col_dict["menubar_bg"]+ ";\n"

        if "fg-inpt: " in line:
            if "wm_color" in gtk_col_dict:
                line = "fg-inpt: " + gtk_col_dict["wm_color"]+ ";\n"
            elif "titlebar_fg_color" in gtk_col_dict:
                line = "fg-inpt: " + gtk_col_dict["titlebar_fg_color"]+ ";\n"
            elif "menubar_fg" in gtk_col_dict:
                line = "fg-inpt: " + gtk_col_dict["menubar_fg"]+ ";\n"


        #if "fg-inpt: " in line:
        #    line = "fg-inpt: " + gtk_col_dict["fg_color"]+ ";\n"

        if "bg-win: " in line:
            line = "bg-win: " + gtk_col_dict["bg_color"]+ ";\n"

        if "fg-nor: " in line:
            line = "fg-nor: " + gtk_col_dict["fg_color"]+ ";\n"

        if "bg-sel: " in line:
            line = "bg-sel: " + gtk_col_dict["selected_bg_color"]+ ";\n"

        if "fg-sel: " in line:
            line = "fg-sel: " + gtk_col_dict["selected_fg_color"]+ ";\n"

        fd.write(line)
    fs.close()
    fd.close()
    return

#copy_to_default(rofi_th_src, rofi_th_dest)

#print("Rofi theme updated to current gtk theme!")





# Here we go!!!

find_home_user()
find_curr_gtk_style_name()
locate_curr_gtk_file()
get_gtk_colors()
parse()
copy_to_default(rofi_th_src, rofi_th_dest)

print("Rofi theme updated to current gtk theme!")
print(gtk_col_dict)


####################


#print(col_lst)













User avatar
Jerry3904
Administrator
Posts: 23047
Joined: Wed Jul 19, 2006 6:13 am

Re: Fluxbox Themes matching GTK themes

#45 Post by Jerry3904 »

That's an exciting project--I look forward to seeing where it goes! I use Rofi more and more these days.

You may know that @Melber and I (mostly Melber) are finishing the first release of "MX Rofi manager," and it would be great to eventually fold your code into it when you got it working as you like. If interested, you can see the current state of that project here:

https://github.com/jerry3904/mxfb-accessories
Production: 5.10, MX-23 Xfce, AMD FX-4130 Quad-Core, GeForce GT 630/PCIe/SSE2, 16 GB, SSD 120 GB, Data 1TB
Personal: Lenovo X1 Carbon with MX-23 Fluxbox
Other: Raspberry Pi 5 with MX-23 Xfce Raspberry Pi Respin

User avatar
Melber
Developer
Posts: 1198
Joined: Tue Mar 23, 2021 4:19 pm

Re: Fluxbox Themes matching GTK themes

#46 Post by Melber »

@purplemoon
Just a heads up, the latest update to rofi v 1.7.1 breaks the restore function for rofi in mxfb-look. The other mxfb-look functions should still work. Will try and fix asap

Outlander
Posts: 33
Joined: Thu May 12, 2022 9:44 pm

Re: Fluxbox Themes matching GTK themes

#47 Post by Outlander »

I modified Clearlooks-Overcast GTK theme and Finetti Fluxbox theme to make a matching set of themes. I can upload them if anyone wants em.

Image

purplemoon
Posts: 41
Joined: Fri Apr 16, 2021 6:10 pm

Re: Fluxbox Themes matching GTK themes

#48 Post by purplemoon »

@Jerry3904 & @Melber I thought I had already answered your posts. But, obviously, not really. So, what else can I say but :bagoverhead: ...

Anyway, after an eternity, I rewrote a script to extract gtk colors from the theme description and load them into a dictionary that is also saved to a file. From there the data can be used for whatever purpose (theme Dunst, Rofi, Fluxbox or desktop widgets...). I am aware that this is not really useful now that Melber has created his powerful tool, but... why not.

So, here is the script that should be run in a terminal for now. It should work with most GTK themes (with GTK2 description). It is split in 2 for (hopefully) later use in a gui.

Code: Select all

import os.path
from configparser import ConfigParser
from os.path import exists
from os.path import expanduser

#from sys_color_theme import *

# EXTRACT GTK THEME COLORS TO A DICTIONARY!

# Get current GTK theme name

print("=" * 43)
print("= Saving GTK theme colors to a dictionary =")
print("=" * 43, "\n")

def get_theme_name():
    
    global path_to_theme
    global gtk_theme_name
# Locate "~/.config/gtk-3.0/settings.ini"
    home = expanduser("~")
    #print(home)
    file_path = "~/.config/gtk-3.0/settings.ini"
    full_file_path = os.path.expanduser(file_path)
# check if the path is correct
    isFile = os.path.isfile(full_file_path)
    
    if isFile :
        print("Path to 'Settings.ini':\n\t", full_file_path, "\n")
# get the gtk theme name from "settings.ini" file
        parser = ConfigParser()
        parser.read(full_file_path)
        gtk_theme_name = parser.get("Settings", "gtk-theme-name")
        
        ########## test other INSTALLED themes ########
        #gtk_theme_name = "Canta"
        ##gtk_theme_name = "Mint-L-Aqua"
        #gtk_theme_name = "Sweet-Dark-v40"
        #gtk_theme_name = "Flat-Remix-GTK-Blue-Darkest"
        #gtk_theme_name = "Simply_Circles_Blue_Dark"
        ###############################################
                
        print("GTK theme in use:\n\t", gtk_theme_name, "\n")

# locate gtk2 theme config file either in:
# "/usr/share/themes/FULL_THEME_NAME/gtk-2.0/gtkrc"
# or in:
# "~/.themes/FULL_THEME_NAME/gtk-2.0/gtkrc"
        gtk_theme_path_1 = "/usr/share/themes/" + gtk_theme_name + "/gtk-2.0/gtkrc"
        gtk_theme_path_2 = home + "/.themes/" + gtk_theme_name + "/gtk-2.0/gtkrc"
        
        if os.path.exists(gtk_theme_path_1):
            path_to_theme = gtk_theme_path_1
            
        elif os.path.exists(gtk_theme_path_2) :
            path_to_theme = gtk_theme_path_2
            
        else:
            print("The file does not exist.")
            
        print("Theme file location: \n\t", path_to_theme, "\n")
        
    else:
        print("Error. The file does not exist.")


# Retrieve the theme colors from the 'grkrc' file.
# Create a dictionary with these and store it
# into a file (dictionary) for future use.

def extract_theme_colors():
    dict_sys_theme = {}
    
    print("List of colors:")
    # start creating a dictionary into a file
    # theme name as a comment
    th_dict_init = "# " + gtk_theme_name + "\n" + "dict_sys_theme = "
    
    # dictionary name / header
    with open("sys_color_theme.py", "w") as dest_file:
        dest_file.write(th_dict_init)
        
    # listing all the colors as key/value pairs
    with open(path_to_theme, "r") as infile:
        for line in infile:
        
            # locate the lines with color data
            if line.startswith("gtk-color-scheme"):
                
            # gtk colors description varies.
                backspace_nb = line.count("\\n")
                
                # colors may be listed on one line each...
                if backspace_nb == 0:
                    
                    # modify data to fit dictionary format
                    line_corr = line.strip("gtk-color-scheme = ").strip().replace(" ", "").strip('"')
                    print("\t", line_corr)
                    x = line_corr.split(":")
                    x_key = x[0]
                    x_value = x[1]
                    
                    dict_sys_theme.update({x_key: x_value})
                    
                    
                # colors may be listed by pairs on several lines...
                elif backspace_nb == 1: 
                    # modify data to fit dictionary format before updating dictionary
                    line_corr_1 = line.strip("gtk-color-scheme = ").strip().strip('"')
                    
                    # now isolate color items in a list
                    lst = line_corr_1.split("\\n")
                    
                    # Isolate keys and values to populate dictionary
                    for item in lst:
                        print("\t", item)
                        x = item.split(":")
                        x_key = x[0]
                        x_value = x[1]
                                                
                        dict_sys_theme.update({x_key: x_value})


                # colors may be listed on a single line...
                elif backspace_nb > 1:
                    # modify data to fit dictionary format before writing to file
                    line_corr_2 = line.strip("gtk-color-scheme = ").strip().strip(" ")
                    line_corr_2 = line_corr_2.replace(" ", "").strip('"')
                    
                    # isolate color items in a list
                    lst2 = line_corr_2.split("\\n")
                    
                    # split each list item to create key/value pairs to populate dictionary
                    for item in lst2:
                        print("\t", item)
                        x = item.split(":")
                        x_key = x[0]
                        x_value = x[1]
                        
                        dict_sys_theme.update({x_key: x_value})

    
    with open("sys_color_theme.py", "a") as dest_file:
        dest_file.write(str(dict_sys_theme))

    print("\nCreated 'dict_sys_theme' dictionary referencing GTK2 colors\nfor'" + gtk_theme_name +"' GTK theme. Data is stored in 'sys_color_theme.py' file.\nSee details below.\n")
    print("dict_sys_theme =", dict_sys_theme)
    print("\nDone.")

# Let's try this!

get_theme_name() 
extract_theme_colors()

If anyone is interested in trying this out and break it, any feedback welcome.

purplemoon
Posts: 41
Joined: Fri Apr 16, 2021 6:10 pm

Re: Fluxbox Themes matching GTK themes

#49 Post by purplemoon »

Here is the corresponding script for theming Rofi. It should work for any style, as long as you modify it accordingly. It should be placed into the same directory as the previous script.

Code: Select all

import os
import os.path
from os.path import expanduser
from os.path import exists

from color_theme_default import *



#def change_rofi_theme():
# get color info from "get_gtk_colors.py",
# if system theme is in use, to update
# 'dict_sys_theme' dictionary in "color_sys_theme.py".
if app_theme == "system":
    import get_gtk_colors

# clear terminal (can be enabled/disabled/(un)commented out)
#os.system('cls' if os.name == 'nt' else 'clear')

# apply new colors to theme
print("=" * 41)
print("= Applying new GTK theme colors to Rofi =")
print("=" * 41, "\n")
print(app_theme)
#print(dict_sys_theme)
# defining rofi theme template name
rofi_th_src_name = "fb_BnW.rasi"
rofi_th_dest_name = "gtk_default_test.rasi"

# setting file paths
home = expanduser("~")

rofi_th_src = home + "/.config/rofi/themes/" + rofi_th_src_name
rofi_th_dest = home + "/.config/rofi/themes/" + rofi_th_dest_name

# check if files exit
isFile_src = os.path.isfile(rofi_th_src)
isFile_dest = os.path.isfile(rofi_th_dest)

# this part is not working!!!
if not isFile_src or not isFile_dest:
    if not isFile_src:
        print("Template file source not found.")
#    else:
#        print("Found template file:", rofi_th_src)

    if not isFile_dest:
        print("File destination not found.")
#    else:
#        print("Destination file already exists and will be modified:\n\t" + rofi_th_src)
    print("Cancel...\nDone.")

if isFile_src: #and isFile_dest:
    print("Template file and destination file found.")
    print("Template file:\n\t" + rofi_th_src)
    print("Destination file already exists and will be modified:\n\t" + rofi_th_src)
    print("\nCopying new data...")
    fs = open(rofi_th_src, "r")
    fd = open(rofi_th_dest, "w")
        #for lines in fs:
    while 1:
        line = fs.readline()
        #print(line)
        if line == "":
            break
        else:
            if "bg-inpt:" in line:
#                print(line)
                line = "\tbg-inpt: " + win_bg + ";\n"
                print(line)
            
            if "fg-inpt:" in line:
#                print(line)
                line = "\tfg-inpt: " + win_fg + ";\n"
                print(line)
                
            if "bg-win:" in line:
#                print(line)
                line = "\tbg-win: " + win_bg + ";\n"
                print(line)
            
            if "fg-nor:" in line:
#                print(line)
                line = "\tfg-nor: " + win_fg + ";\n"
                print(line)
            
            if "bg-sel:" in line:
#                print(line)
                line = "\tbg-sel: " + sel_bg + ";\n"
                print(line)
            
            if "fg-sel:" in line:
#                print(line)
                line = "\tfg-sel: " + sel_fg + ";\n"
                print(line)
        
        fd.write(line)
    fs.close()
    fd.close()

    print("Done.")

It should be compatible with any GTK theme.
Below is an example of my Rofi minimalist theme matching Matcha Dark Aliz GTK theme and an experimental Fluxbox style - in the hope that it can be themed with a similar script in the future. For now, Fluxbox buttons are an issue...
sc_test.jpg
You do not have the required permissions to view the files attached to this post.

Post Reply

Return to “MX Fluxbox Official Release”