Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

White line rendered on left edge of wallpaper #30

Open
orchetect opened this issue Jan 12, 2021 · 10 comments
Open

White line rendered on left edge of wallpaper #30

orchetect opened this issue Jan 12, 2021 · 10 comments
Labels
help wanted Extra attention is needed

Comments

@orchetect
Copy link

orchetect commented Jan 12, 2021

On my late-2016 13" MacBook Pro, wallpapers processed through ChangeMenuBarColor always render a single-pixel wide white line along the left edge of the wallpaper. Doesn't matter if the source image was a dynamic wallpaper or normal static image.

I have the screen res scaled at "More Space" 1680x1050 in System Preferences (up from the native res of 1440x900).

However on my desktop Mac running Catalina on a non-retina (native res) screen, this doesn't happen.

Without digging into the source code, I'm not sure what causes this but it may be related to subpixel coordinate rounding?

white-line

Zoomed in. You can see a solid white line 1 pixel wide, then a mid-point alpha blend of 1 pixel wide next to it.

white-line2

@igorkulman igorkulman added the help wanted Extra attention is needed label Jan 12, 2021
@igorkulman
Copy link
Owner

To be honest I have no idea why this might happen. The utility does not draw a white line there. Must be some macOS rendering thing.

@igorkulman
Copy link
Owner

Maybe #33 might help if you run a display with some scaling.

@chriswep
Copy link

i have the same issue on one of my 3 displays. its a 1440p screen that runs in 1080p hdpi mode. however the issue remains if i set the display to 1080p non-dpi. strangely enough, if i run it without scaling at native 1440p, the menu bar size is about one third of the screen. other two displays without issues (both running at non-2x dpi modes).

@Waitsnake
Copy link

Waitsnake commented Oct 31, 2022

I have the same issue on my M1 2020 MBA with 2560 by 1600 native resolution.

When scaling screen by OS to 1280 by 800 and then running on ChangeMenuBarColor on original picture the white line is on the bottom edge of the wallpaper not on left.
white_line_on_bottom

When scaling screen by OS to 1440 by 900 (Standard by OS) and then running on ChangeMenuBarColor on original picture there is no white line at all.

The source picture was 5472 × 3072 and after ChangeMenuBarColor did all of its resizing, croping and image combining the resulting picture was 2560 × 1600.

Also looked through the source code but also have no clue where it is coming from. If it is really bug within ChangeMenuBarColor I would assume that I would see the white line for 1280 by 800 and 1440 by 900 scaling. But since this is not the case there is maybe a bug in the API from macOS(?).

@Waitsnake
Copy link

I created a Xcode project and imported all swift files and added all dependencies (Files, ArgumentParser and Rainbow) to debug this stuff.
I found out so far that for my "5472 × 3072" picture the NSImage load of the file already contains different values in the size attribute that did not mach the original size of the image but smaller fractional values "2188.8000000000002 x 1228.8000000000002".

The fractional values are set directly after loadWallpaperImage() of Commands.swift loads them with NSImage().

        guard let path = NSWorkspace.shared.desktopImageURL(for: screen), let wallpaper = NSImage(contentsOf: path) else {
            Log.error("Cannot read the currently set macOS wallpaper. Try providing a specific wallpaper as a parameter instead.")
            return nil
        }

Continuing with those fractional dimension values instead of the original integer dimensions for further calculations will then of cause lead to a hole bunch of unwanted side effects in the rest of the code.

I searched for this issue that NSImage did not give the real size values for some pictures and found this thread here:
https://stackoverflow.com/questions/9264051/nsimage-size-not-real-size-with-some-pictures

They confirmed the issue that NSImage size method returns size information that is screen resolution dependent and they have an example code that uses NSBitmapImageRep to detect the real size of an image. A second example uses the attribute "representations" of NSImage that is an array of NSImageRep and iterate over it to get the real image size.

@igorkulman
Copy link
Owner

@Waitsnake thanks for the research, the link to SO looks promising. I will take a look. Feel free to open a PR if you want to tackle it yourself.

@Waitsnake
Copy link

Waitsnake commented Oct 31, 2022

Adding those 3 lines of quick and dirty code after loading the image and that already fixed it for me when running the program in Xcode.

        guard let path = NSWorkspace.shared.desktopImageURL(for: screen), let wallpaper = NSImage(contentsOf: path) else {
            Log.error("Cannot read the currently set macOS wallpaper. Try providing a specific wallpaper as a parameter instead.")
            return nil
        }
        
        let rep = wallpaper.representations[0]
        let imageSize = NSSize(width: rep.pixelsWide, height: rep.pixelsHigh)
        wallpaper.size = imageSize

I pushed it on my fork to try it with mint but in mint I had the same effect as before?
Is the swift dialect in Xcode and in mint any different? Maybe wallpaper.size could not overridden?
I'm confused why it behaves differently.

It will be much more time intensive to the debug the code in mint by only using log entries then using a real debugger from Xcode.

@igorkulman
Copy link
Owner

Adding those 3 lines of quick and dirty here after loading the image and that already fixed it for me when running the program in Xcode.

        guard let path = NSWorkspace.shared.desktopImageURL(for: screen), let wallpaper = NSImage(contentsOf: path) else {
            Log.error("Cannot read the currently set macOS wallpaper. Try providing a specific wallpaper as a parameter instead.")
            return nil
        }
        
        let rep = wallpaper.representations[0]
        let imageSize = NSSize(width: rep.pixelsWide, height: rep.pixelsHigh)
        wallpaper.size = imageSize

I pushed it on my fork to try it with mint but in mint I had the same effect as before? Is the swift dialect in Xcode and in mint different? Maybe wallpaper.size could bot overridden? I'm confused why it behaves differently.

It will be much more time intensive to the debug the code in mint by only using only log entries then using a real debugger from Xcode.

I think with mint you need to have a version tagged, it will not just take the latest commit from the master branch.

If it works fine from Xcode it should be fine, you can also try running it from terminal via swift run ChangeMenuBarColor SolidColor "#color" wallapper_path from the project directory, this should be equivalent to what mint does.

@Waitsnake
Copy link

Waitsnake commented Oct 31, 2022

I'm not so familiar with mint apart from using it. So I don't know the exact step for deployment yet.

Edit later:
Ok, I just tagged my master brach with v1.0.2 and uninstalled ChangeMenuBarColor from mint and installed it again and indeed it installed v1.0.2. When running my script with the same "5472 × 3072" picture in my 1280 by 800 scaled enviroment, the white line is now gone also when using mint.

So the fix in principal works. I know my code was just quick and dirty to quickly see if it fixes the issue or not. But it can be done more bullet prof with some guards and also not just picking the first element of the array via representations[0] (I saw this in one of the examples but I'm not sure if "0" contains always the biggest size of the image), but rather iterating over the complete array using representations.count and then find the biggest size for the image.

@igorkulman
Copy link
Owner

Hopefully 63dd5d6 fixes the this problem as suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants