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

Edge case where label text is not displayed #54

Closed
Dretch opened this issue Dec 31, 2021 · 12 comments
Closed

Edge case where label text is not displayed #54

Dretch opened this issue Dec 31, 2021 · 12 comments
Labels
bug Something isn't working correctly

Comments

@Dretch
Copy link
Contributor

Dretch commented Dec 31, 2021

Hello,

I have found an edge case where the text on a label does not get drawn.

The UI code looks like this:

buildUI
  :: WidgetEnv AppModel AppEvent
  -> AppModel
  -> WidgetNode AppModel AppEvent
buildUI wenv _model =
  hstack [
    label "a" `styleBasic` [paddingH 4]
  ]

Reducing paddingH to 3 makes the "a" show up. Changing "a" to "b" also makes the text show up.

Example with text not showing:
Screenshot at 2021-12-31 12-49-43

Example with text changed to "b" and therefore showing:
Screenshot at 2021-12-31 12-50-11

I have also attached a modified hello world that demonstrates this phenomenon:
monomer-label-text-not-displayed.zip

I suppose there is some edge case in the text rendering code that is not working quite correctly.

PS. Sorry for logging bugs! My experience with Monomer is actually really positive: I am converting a gi-gtk-declarative app and although it is not completely trivial (e.g. I am hacking together a 2d-grid container like Gtk Grid), it has been pretty easy to bend Monomer to my will.

@fjvallarino
Copy link
Owner

Hi! No problems at all about reporting bugs! It's super helpful for me, thanks!

I will take a look as soon as possible, although I may not be able to do it today. I just wanted to suggest you take a look at Grid.hs if you are creating a custom layout widget. It's the most basic layout provided by the library, since it assigns the same space vertically/horizontally to each widget, and it may give you a general idea about how you can implement your own. Stack.hs may be interesting too if you want to assign the available space according to what widgets requested.

@Dretch
Copy link
Contributor Author

Dretch commented Dec 31, 2021

I will take a look as soon as possible, although I may not be able to do it today.

Thanks :) (there is no rush though!)

I just wanted to suggest you take a look at Grid.hs ... Stack.hs

Indeed, I have been looking at these and it has been useful. 👍

@fjvallarino fjvallarino added the bug Something isn't working correctly label Dec 31, 2021
@Kyarigwo
Copy link
Contributor

I have been myself trying to track down what I think might be the same edge case, which, as you might expect, seems to be due to floating point math. My own test code is:

buildUI
    :: WidgetEnv AppModel AppEvent
    -> AppModel
    -> WidgetNode AppModel AppEvent
buildUI _ _ = widgetTree where
    widgetTree =
        vstack [
            buildLine "Previous" 1.0,
            buildLine "Previous" 0.75,
            buildLine "Previous" 0.5,
            buildLine "Previous" 0.0,
            buildLine "Previousthing" 1.0
            ] `styleBasic` [bgColor slateBlue]

buildLine :: Text -> Double -> WidgetNode s e
buildLine caption pad =
        hstack [
            label caption `styleBasic` [padding pad, bgColor darkGreen]
        ]

Which gives an output of:

Screenshot from 2022-01-14 16-00-08

The issue appears to be that the function getTextLinesSize in Text.hs, line 192 called for the string 'previous' returns a value of 62.666666666666664. When the sizeReqAddStyle function in SizeReq.hs is called for a padding of 1.0 it adds 2.0, and the result of 62.666666666666664 + 2.0 is 64.66666666666666.

There are 14 6s in each case, so the two values are:
62.666666666666664
64.66666666666666

When the label widget tries to determine if the text overflows the given view port, it removes the padding of 2.0, and then checks if the width of the text, 62.666666666666664, is greater then the view port width, 62.66666666666666, which it is, so it truncates the text.

The same issue happens when adding a padding of 0.75, which adds 1.5. However, with 1.0 the sum is 63.66666666666666, hence no truncation. I expect that this will depend on font chosen, the exact text etc.

I am not sure what would the best way to handle this. Perhaps introducing a small tolerance to determine if the text should be truncated? But I'm not sure what else that might effect.

@fjvallarino
Copy link
Owner

Hi! I'm a bit puzzled. I just tested the two examples (@Dretch's and @Kyarigwo's) in macOS Monterrey and Ubuntu 21.04, and they work fine on both platforms. I tried resizing and changing padding, but I could not reproduce the issue.

Which OS/version are you using?

I'll review the overflow code. I can add some tolerance to account for these rounding issues; since widgets are responsible for applying a scissor if their content may overflow, an extra character should not cause problems.

@fjvallarino
Copy link
Owner

Doing a bit of debugging, I added a traceShow call to getTextLines, and the results I get are a bit different:

Size {_sW = 62.5, _sH = 16.0}
Size {_sW = 62.5, _sH = 16.0}
Size {_sW = 62.5, _sH = 16.0}
Size {_sW = 62.5, _sH = 16.0}
Size {_sW = 98.5, _sH = 16.0}

I assume the 62.666666666666664 you're getting corresponds to the 62.5 I got, but I wonder what is causing the difference...

@fjvallarino
Copy link
Owner

So far, I have not been able to reproduce the issue, but it's clear that it happens. Unfortunately, this means I can't create unit tests for future scenarios. I'm wondering if the problem is CPU-dependent, OS-dependent, or some other thing.

Just in case, I created a branch that includes a simple check that hopefully helps with this issue. Originally, I planned to check for a percent difference, but maybe it's not necessary. To use it, you will need to update your stack.yaml:

- git: https://github.com/fjvallarino/monomer.git
  commit: b503405102ddc1ea25ff8cd36738abc5f1a4ee27

If you get a chance to test it, please let me know if it works for you.

Thanks for the detailed reports!

@Litoprobka
Copy link

Litoprobka commented Jan 14, 2022

The fix works for me.

(original bug happens)
System specs: Ryzen 5600g, no GPU, Void Linux, xmonad, X11

@Kyarigwo
Copy link
Contributor

Kyarigwo commented Jan 15, 2022

The fix works for me as well.

On the main branch the issue occurs even for the Todo example for me, so I expected it to be specific to my machine setup.

My graphics card is a Nvidia GTX 1060, OS is Ubuntu 20.4.3, GNOME version 3.36.8, windowing system is X11.

I also need to use the appRenderOnMainThread switch.

@fjvallarino
Copy link
Owner

@Litoprobka @Kyarigwo thanks for reporting it works for you!

I'll merge the PR to main, so it's included in the next release.

@Dretch
Copy link
Contributor Author

Dretch commented Jan 18, 2022

The fix works for me too.

Also, I noticed that the issue only happens when I start the app on my laptop screen. When I start the app on my external screen (higher resolution and higher pixel density) then everything bigger (as in, it uses more pixels) -- which is another issue by itself, I guess -- and the issue does not occur.

So perhaps the issue is related to HDPI-scaling, or something...

@fjvallarino
Copy link
Owner

I'm interested in the external monitor situation. Is this on Windows? There are some DPI calculations/adjustments in Platform.hs when the application starts, but they are not applied when the window is moved to a different screen.

If you are launching the application on the laptop's screen and then moving it to the external monitor, maybe that's the cause for the bigger item size; I have not had the chance to test this scenario, since I use a laptop for testing on Windows. Alternatively, you can provide the appScaleFactor configuration when the application starts.

I'll close this issue since the fix is already on main. Maybe we can move the DPI discussion to a new issue.

Thanks @Dretch @Kyarigwo @Litoprobka for the help figuring this out!

@Dretch
Copy link
Contributor Author

Dretch commented Jan 23, 2022

I'm interested in the external monitor situation. Is this on Windows?

This is on Ubuntu Mate 20.04. I think the problem is that this uses X11 rather than Wayland -- and Platform.hs says "Currently only tested on Wayland (Ubuntu 21.04)". It seems Mate is going to get Wayland support soon anyway, so maybe this issue will disappear (at least for me) ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctly
Projects
None yet
Development

No branches or pull requests

4 participants