-
-
Notifications
You must be signed in to change notification settings - Fork 723
Add units support for polybar #1651 #951 #1671
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
Conversation
|
I fixed the unit tests. Should I add a test for the function |
|
I just remove some bugs (negative margin, padding...). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I jotted down a bunch of thoughts I had about this. (almost) nothing here is set in stone, I'd appreciate your thoughts as well.
Thanks a lot for putting your time into this, I'm really excited to get this functionality inside polybar.
DPI initialization is now in the constructor of the bar. However this initialization seems strange, the DPI are only computed if dpi < 0 is explicitly specified in the configuration (see below). If the DPI isn't specified in the configuration, the default value is 96. Is it the correct behavior?
Moving it into bar.cpp is fine. I don't know what the original intention was. But since that part of the code is over 2 years old, I'd say it's the expected behavior now ;)
One thing that concerned me when writing up the instructions in #1651 was that SPACE doesn't make sense in the offset format.
I think we need to separate how we specify sizes and spacing.
Spacing can be in spaces, pixel, or points while size can be percentages, pixel, points or those combined in the offset format.
I first thought we can keep this together because it has lots of things in common (POINT and PIXEL), but I don't think this is worth it.
The more I think about it, the less I am a fan of converting points to pixels only when the value in pixels is needed and passing around point values. I know this is actually what I suggested we do originally because the builder would be the only place where this conversion happens. But this would make things quite inflexible because if we ever extend our code we would need to do the conversion in all places that use those pixel values.
Ideally we would get back and pass around only structs like this for spacing:
enum size_type { SPACE, PIXEL };
struct size {
enum size_type type;
ssize_t value;
}and everything else is handled by the config. I said before that I am not a fan of the config knowing about the dpi but it seems to me this is the only way to get a clean interface for this.
I am planning on separating the config into two parts anyway: One part just accesses the config data structures and returns a string for a given key, the other part takes that string and converts it into whatever type is needed. The current way of using templates for everything in the config seems a bit messy to me. Since we will have such a separation anyway and there the part that converts things may actually know about dpi and other things from the outside, we could store dpi_x in the config as a temporary fix (and mark it as such). We only store dpi_x because spacing will always be in the x-direction.
We don't have the same problem with sizes and the geometry format because there we need to call a special function to get pixel values anyway and so we can just pass the dpi there.
The last thing is about what type the values should have. You made it very generic by using templates.
As far as I can tell, the following are the strictest types we can have for the different units:
spacing:POINT:float >= 0PIXEL:size_tSPACE:size_t
size:POINT:floatPIXEL:ssize_t
If we actually want to use these types, we'd have to use union inside the structs. This may be too cumbersome though, because we would have to have multiple if-else blocks whenever we use it.
For spacing, if we implement it as I described just above, the config will anyway just return either PIXEL or SPACE, so we can use size_t there.
For size, we could also use float for everything and when converting to pixels, we just cast to size_t.
EDIT: Since we use the %{O tag, the POINT and PIXEL values for spacing can also be negative. So using float everywhere is fine.
If that's the expected behavior, maybe the documentation/wiki should be modified to state that any value <= 0 cause the DPI to be auto-detected. Moreover, this detection is bugged, since if I change the resolution of my screen (like when I duplicate my laptop screen and the projector is in 4/3), I have to relaunch polybar to update this value. (Maybe an x event should cause the value to be updated)
I agree, I tried to do my best but this is really confusing.
The following paragraph supposes that the DPI might become dynamic otherwise its content should be ignored. For that point, I think this might be a problem if the DPI changes during the execution. struct space_size {
space_type type;
// If type == space_type::pixel converts the value in pixel if necessary and returns it.
// Otherwise returns the size in number of spaces.
// No need to use float in the return type since pixel or space doesn't need them.
ssize_t get_value() const {
if (type == space_type::point)
return convert_to_pixel(settings::get_instance().get_dpi_x(), value);
else
return value;
}
private:
// to be sure that nobody uses it directly
float value; // could be an union if you want since the get_value is the only place
// were the union will be used.
};The geometry_size struct could be defined in a similar way with an enum type like that: enum class geometry_size_type { PERCENTAGE, POINT, PIXEL }
Do you want me to use a plain C enum or may I use an enum class? (I prefer using enum class to avoid global namespace pollution) What do you think of this? |
|
Everything within the bar except for the modules themselves is quite static. Polybar cannot dynamically change its size or position when changes to the monitor occur. All of this is handled through It is conceivable that we want to make things more dynamic in the future. But even then, I would not convert to pixels in the builder but rather extend the Adding
Wouldn't
You can use enum class. I just used enum because I'm more familiar with C ;) |
I didn't know it worked that way, but that's seems logical with the fact that some of my modules are reset when I change my resolution.
Maybe I can tried to do that to see if it is more clean. (Extends the
Yeah my bad, it is just point and pixel. |
|
By the way, do you have an idea for naming the enums and structs associated with that:
Each time I found a name it is either bad or already taken (like |
|
Since we probably put these inside a namespace, naming is not such a big issue, but I think the following names are reasonable. Feel free to improve them. enum class size_type { POINT, PIXEL }
enum class space_type { POINT, PIXEL, SPACE }
struct spacing {
space_type type;
...
}
struct geometry {
float percentage;
size_type offset_type;
...
} |
|
I just finished some modifications to take your review in account. Just as expected, there are two structures, one for spacing and the other for size. |
patrick96
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finally got around to reviewing this. Thanks for your patience ;)
Did some rough testing and things seem to work fine with actually emitting and parsing the offsets. Will do some more thorough testing once the other issues are resolved.
You also need to resolve the merge conflict that was likely caused by us removing icon_t in #1553.
The issue in #1700 is still not totally fixed. Offsets do produce spaces that have the proper background color, but the string I used in #1700 still does not look the same as with lemonbar:
%{O100}Filler%{B#ff0000 O100}First%{O200}Second%{O-100}
With this PR:
With lemonbar:
You see, Second is not displayed with this PR:
|
It would probably be useful if we also allow the use of these units in |
Fixed by fd7322b |
b2ec470 to
fd7322b
Compare
If I am not wrong |
|
I just added a commit that fixes #1814. |
|
I think you should make a separate PR and resolve the merge conflict once one of the two is merged. |
Commit removed. See my new PR #1817. |
- add a size_with_unit struct - add a geometry_format_values struct - move dpi initialisation from renderer.cpp to bar.cpp - add a string to size_with_unit converter - add point support (with pt) - add pixel support (with px)
patrick96
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems it's taking me longer and longer to find time for these reviews. Hopefully the next time you won't have to wait so long.
I'm very happy with this 😃. I don't see any immediate defects and it does make the whole spacing and size handling more uniform. I mainly commented on small stuff and the naming of these new concepts.
The only thing we need to think about whether or not to allow negative values for spacing. Theoretically we can allow negative values for px and pt spacing but not for actual spaces. In this PR, as far as I can see, all negative values are disallowed (in order to fix #1265).
I think we should allow negative values for points and pixels and only throw an error for negative spaces.
After this we probably just need one last review and some more testing and then we can merge this.
Please also run clang-format on all the files you touched, I think you missed some:
clang-format -i $(git log --name-only --pretty=oneline --full-index 1caed747fd2991d67fee122e3fff1ba01b9dcdaf^..41381ee7038a18678ad88117971f53bbc6a3be47 | \grep -vE '^[0-9a-f]{40} ' | sort | uniq)|
Can this be rebased against master please |
|
I squashed and rebased this against master (I tried to rebase without squashing but kept screwing up the history, so figured I didn't need to keep it anyway just to build and run it) I rely on this fork to have polybar even remotely usable when changing DPI. Please consider reviving it @Lomadriel |
|
Any way to help get this PR merged? E.g. implement requested code changes? I'd really love to see these units to improve HiDPI support 👍 |
|
Until now I've been rebasing this PR onto master, but fd55652 was a big change that will not be a trivial change to rebase onto. I may or may not attempt to fix this up again, depending on how hard it seems to be |
|
@frebib If you do attempt to resolve the conflicts and want to help get this merged, a PR would be very much appreciated :) And of course, ask if you need help. I think most conflicts should be quite straighforward (just tedious to get the changes from both sides in), but in the renderer and parser, it might be more difficult because there we actually changed the places where the offset handling happens. |
|
@patrick96 I can certainly give it a go, but I'm not at all familiar with C++ or much of the syntax/language features. |
Yeah, that's fine. This would have happened with this PR anyway, I think.
In that case, this might get tricky. Let me know, if you need any help.
Yeah, I don't think this PR touches the tray at all. Feel free to leave out units in the tray if that's easier. First priority should be to get the overall framework working. |
|
I gave it a go. Seems to compile & run the same as the old builds did for me. |


Implement feature requested in #1651 and #951.
This pr add supports for
px(pixel) andpt(point) for polybar.I followed the advices given by @patrick96 in #1651, so I add a
size_with_unitstructure to store the value and the unit. Unlike thesizedefinition, the value is signed to handle negative offset.To handle the
widthandheightproblem, I added ageometry_format_valuesstructure which contains a percentage and the offset (asize_with_unitstructure).builder::spacenow uses the%{O}formatting tag but this is handled bysize_with_unit_to_stringhelper in the new header"utils/unit.hpp"to avoid duplicate code (this function is also used incontroller.cppsince I can't usebuilder::spacehere).DPI initialization is now in the constructor of the bar. However this initialization seems strange, the DPI are only computed if
dpi < 0is explicitly specified in the configuration (see below). If the DPI isn't specified in the configuration, the default value is 96. Is it the correct behavior?https://github.com/Lomadriel/polybar/blob/cc4e09edc41cfbd5f2f4bf7235470aa1c21bc59a/src/components/bar.cpp#L155-L178
The rest of the PR is just adapting the code to use these structures. I tried to find all keys that could uses units but I am not sure if I added units support for all the key that could benefit of this feature.
EDIT: Fixes #1700
TEAMEDIT:
Closes #1651
Closes #951
Fixes #1265