Neamar / KISS

Lightning fast, open-source, < 250kb Android launcher
https://kisslauncher.com/
GNU General Public License v3.0
2.98k stars 582 forks source link

Change KISS' App-Color in Accordance with "Main Color" #1654

Open Glitchy-Tozier opened 3 years ago

Glitchy-Tozier commented 3 years ago

Is your feature request related to a problem? Please describe. Apparently Apps have some color-attributes in their Code that tell other Apps (like keyboards or launchers) what color they are. KISS is green

However, KISS doesn't change it's app-color when the user goes into the settings and changes colors there. This results in nice skins like this one... Screenshot_20210126-161946_KISS launcher.jpg ...getting massacred by keyboards with adaptive color-themes. The keyboard pops up: Screenshot_20210126-162027_KISS launcher.jpg

Describe the solution you'd like Change KISS' App-Color in Accordance with the main color the user has set in the settings.

Describe alternatives you've considered, or that are already available within KISS Turning off the keyboard's adaptive color-themes is an solution, obviously. However, it would be better if KISS properly represented it's current colors better.

Neamar commented 3 years ago

Oh that's a funny one, I didn't know keyboard had this feature! That's GBoard?

I'm not sure where the keyboard gets this color from though. Do you happen to have any documentation on this topic?

patrickgold commented 3 years ago

Hi there, I am the dev of FlorisBoard (the keyboard you see in the above screenshot) and who also implemented adaptive themeing. As there's little to no documentation to this topic, I am happy to help out here.

First off, this is the code which I currently use to extract app color values based on the packageName: https://github.com/florisboard/florisboard/blob/915bcec0ee988c35fcf06028cd531833f0667e46/app/src/main/java/dev/patrickgold/florisboard/ime/theme/ThemeManager.kt#L111-L220

This method uses the Android PackageManager to get the Application object of an app as well as the launch activity and tries to parse the attributes colorPrimary, colorPrimaryDark and colorSecondary from the returned theme reference. These colors are then used to color the keyboard UI elements. I am not even sure if there's any official documentation for this exactly, but the above method is based on this StackOverflow answer: https://stackoverflow.com/a/27138913/6801193

The problem I see is that the returned colors are statically compiled into the APK and there's no way to dynamically set this. The only thing you could try is to override your Resources class, where you return dynamic colors for these attributes (based on the preferences of the user), which my keyboard would be able to pick up then. Kinda like this pseudo Kotlin code:

class CustomResources : Resources {
    override fun newTheme(): Resources.Theme {
        return CustomAndroidTheme()
    }
}

class CustomTheme : Resources.Theme {
    override fun obtainStyledAttributes(...): TypedArray {
        return CustomTypedArray()
    }
}

class CustomTypedArray : TypedArray {
    override fun getColor(colorId: Int): Int {
        if color == colorPrimary then return kissPreferences.getMainColor()
        else if color == colorPrimaryDark then return kissPreferences.getMainDarkColor()
        else if color == colorSecondary then return kissPreferences.getOtherColor()
        else return super.getColor(colorId)
    }
}

Then in your Application class you override your getResources() method and return a CustomResources() object. I am not 100% sure though if this works, but it might be worth a shot.

If you need another keyboard to try this out, AnySoftKeyboard also has adaptive themeing which works similar to FlorisBoard's in the mechanism we use to retrieve other app's colors.