Closed deanishe closed 10 years ago
WTF? It had been working perfectly for me, and now it's not. Are you on Yosemite or Mavericks?
Maybe I've gotten more sleep today than the last time I was trying to sort through the code, but the Objective-C seems to make more sense in that it doesn't do exactly what we need it to do.
I will say, the LightOrDark was working, but now it's not...
I just pushed the source that I used to compile the utility to a new repo, and I added you both as collaborators.
Basically, what the utility needs to do is
light
or dark
; andWe could do everything above in a regular script except for 3. The reason why is that the plists store the colors as Objective-C colors, and I haven't seen a way to convert them to something usable (hex?). If we can find out a way to do that, then I can just rewrite the above as a script. Otherwise, let's see if we can tweak the code.
Updating:
~/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist
to get
appearance.theme
syncfolder
syncfolder
is not set, then fallback to default at ~/Library/Application Support/Alfred 2/
syncfolder/Alfred.alfredpreferences/preferences/appearance/prefs.plist
themes/<appearance.theme-value-from-step1>/background
So, here's an example colorspace that I've found in step 4:
BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU0NvbG9yAISECE5TT2JqZWN0AIWEAWMBhARmZmZmAAAAAYY=
If I base64 decode that, then I get streamtyped���@���NSColor�NSObject��c�ffff�
Okay. The reason why it's not working anymore is, that, for some reason, the theme name isn't being updated in ~/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist
.
appearance.theme
stays the same no matter what, even if I change it. My current value in there refers to the theme that I usually use, which is light
, so it keeps returning those values. The utility is working in the sense that it pulls the relevant information out of the plists.
When I change the theme, then the appearance.theme
value doesn't change. So... where is Alfred now storing this value?
I just emailed Andrew to ask him that last question of where it's currently being stored. Putting this on hold because I can't track down the file.
It's in Alfred.alfredpreferences
(which may be somewhere in Dropbox).
When I change theme, the file that contains the actual ID of the currently selected theme (i.e. the file that actually changes) is:
preferences/local/3b199235f622c5e93b5731756e19867edfb2f354/appearance/prefs.plist
I'm using the brand-new development version however (w/ proxy support), and that local
directory was created today, so it might be somewhere else in the stable version.
Looks like its there for me as well. Good to know. That will make it hard to find (for me to get the last dir) in objective-c if it stays there. We might be able to do something to where we get the current version of Alfred and change it depending on that. Andrew said he'd send me a better explanation in a bit, so I'll update this with that information soon.
If there's only one directory, it shouldn't be a problem. I'm wondering if that random number is some kind of machine ID, which will make it a PITA to work out which is the current machine unless Andrew spills the beans on the ID generation.
With most scripting languages we can just "wildcard" it, so it wouldn't matter. I'm assuming that we can do that in Objective-C. If not, then we can alter the binary to take an argument that's the plist, and we can determine the directory via wildcard path completion and send it to the binary.
However, @Ritashugisha knows much more than we do about Objective-C.
On this topic: what about darkening a light icon? Is that possible? (I don't really understand what the conversion code is doing: I just translated the PHP to Python.)
Does the user have to specify the dark icon if they want to use the automatic alteration?
If that's the case, I'd consider renaming the arguments to icon()
.
In that case, @Ritashugisha should perhaps take over. Or we bust the Objective-C code down to "give me the background colour in theme XXX as HSV/RGB". My suggestion would be the former: it's going to run a lot faster in Objective-C.
It either darkens or lightens. The V space is calculated as a float between 0 and 1 with .5 as neutral. So, the algorithm takes the initial V and subtracts it from 1, which will either lighten or darken the image and keep the "light/dark" distance from the neutral point. So .3 would turn into .7, and .7 would turn into .3.
An easier example is ffffff
evaluates to RGB 255,255,255
and HSL 0, 0, 1
. So, the algorithm would return an HSL of 0, 0, 0
(1-1=0), which converts to RGB 0,0,0
and Hex 000000
.
It might run a lot faster, but the utility is only called to evaluate the background right now.
Evaluating the icon is done in the script. Calling it in the script saves us the expensive system calls, and caching the alternate colors makes it even faster.
From Andrew: v2.4 b277 pre-release just came out that includes these environmental variables:
"alfred_preferences" = "/Users/{USERNAME}/Dropbox/Alfred/Alfred.alfredpreferences";
"alfred_preferences_localhash" = {HASHFORYOSEMITE};
"alfred_theme" = "alfred.theme.yosemite";
"alfred_theme_background" = "rgba(255,255,255,0.98)";
"alfred_theme_iconstyle" = dark;
"alfred_version" = "2.4";
"alfred_version_build" = 276;
"alfred_workflow_uid" = "user.workflow.FDE54875-6670-45CC-9D6B-1879F9257FBB";
The latter is obviously the path to the workflow. Nice.
Since LightOrDark works on earlier versions, we can always test to see if these environmental variables exist, and, if they don't, then we can fallback to the old logic.
Sound good?
It either darkens or lightens
Oops. Need to rename some stuff and adjust the logic.
Calling it in the script saves us the expensive system calls, and caching the alternate colors makes it even faster
I thought we needed Objective-C to parse the colour?
True. We need Objective-C to parse the colo(u)r from the Alfredplist, but we have to deal with the NSColor object only with the theme value, which the binary does for us. And it returns the light
or dark
, which is all we need to know about the background.
The colo(u)rs for the icons, however, are still hex values, and we don't need Objective-C to parse those. We could have the binary parse the hex color for us, but then we'd have to make a system call for each icon that has the "alter" flag set rather than just staying with native code.
Actually. We don't need the LightOrDark binary at all for v2.4.277+. We can use the alfred_theme_background
environmental variables to calculate the value.
Here is the new PHP code to test for the light/dark theme when 2.4.277+ in case the logic helps with other languages. I put this in the __construct() method.
if ( isset( $_ENV[ 'alfred_version' ] ) ) {
// As of Alfred v2.4 Build 277, environmental variables are available
// that will make this process a lot easier and faster.
$this->alfredVersion = array( 'version' => $_ENV[ 'alfred_version' ],
'build' => $_ENV[ 'alfred_version_build' ]);
$this->home = $_ENV[ 'HOME' ];
$this->alfredPreferences = $_ENV[ 'alfred_preferences' ];
$this->preferencesHash = $_ENV[ 'alfred_preferences_local_hash' ];
$this->themeBackground = $_ENV[ 'alfred_theme_background' ];
$this->theme = $_ENV[ 'alfred_theme' ];
$plist = "{$this->alfredPreferences}/preferences/local/{$this->preferencesHash}/appearance/prefs.plist";
if ( ! file_exists( "{$this->data}/data" ) ) {
mkdir( "{$this->data}/data", 0775, TRUE );
}
if ( file_exists( "{$this->data}/data/theme_background" ) ) {
if ( filemtime( "{$this->data}/data/theme_background" > $plist ) ) {
$this->background = file_get_contents( "{$this->data}/data/theme_background" );
} else {
$update = TRUE;
}
} else {
$update = TRUE;
}
if ( isset( $update ) && ( $update == TRUE ) ) {
// See if RGB value is greater than 127, if so, background is light,
// else, dark
preg_match_all("/rgba\(([0-9]{3}),([0-9]{3}),([0-9]{3}),([0-9.]{4,})\)/", "rgba(236,237,216,0.00)", $matches);
$r = $matches[1];
$g = $matches[2];
$b = $matches[3];
if ( ( ( $r * 299 ) + ( $g * 587 ) + ( $b * 114 ) ) / 1000 > 127 )
$this->background = 'light';
else
$this->background = 'dark';
file_put_contents( "{$this->data}/data/theme_background", $this->background );
}
} else {
// Pre Alfred v2.4:277.
// Do stuff here
$this->setBackground();
}
Added in 731130472553145796fd4be4946bf6ac0303fb98
Whoops. Forgot some code. Altered it above. Fixed it in a462bf2d512e301f34c6d0bd02f43718b27bfe76
I added this behaviour to the Python version, too.
Am I right in thinking the utility no longer needs changing? It works as before on version 2.3, and the environmental variable method works on 2.4+?
You are correct, sir.
But, with the new bundle id
and name
environmental variables (as of today), we now can remove most of the plist interfacing that we need (well, keep it as a backup).
For testing purposes, we can just use scripts that export
the bundle id
and name
variables so that we don't have to test from inside Alfred. It'll also make writing the automated tests easier.
I'm closing this issue as fixed.
I've tried changing themes, but the
LightOrDark
util always returnslight
. Even with a black theme.