Open fmarier opened 1 year ago
Thanks for the ticket :)
Just to clarify: Currently, if the font file is missing, no font is rendered at-all? It doesn't currently fallback to system fonts? If fallback is broken, that's terrible. I would expect that kivy would already handle this..
I know you build BusKill different from me. Could you please post the steps to reproduce this?
I certainly plan to add the ability for a user to customize the font face and size after #16 unblocks #37.
But I'm on the fence if I want the BusKill app to actually default to the system-defined font. I guess I would be open to this if I could programmatically determine if the system font is set to either [a] the OS default or [b] if the user explicitly customized the system font. If the system font was explicitly set by the user, then I agree it should default to the system font (eg for accessibility reasons).
Currently if the font is not in the expected directory (fonts/
from where buskill_gui.py
lives), then a fatal exception is thrown and the application exits:
Traceback (most recent call last):
File "/usr/share/buskill/main.py", line 139, in <module>
from buskill_gui import BusKillApp
File "/usr/share/buskill/buskill_gui.py", line 533, in <module>
class BusKillApp(App):
File "/usr/share/buskill/buskill_gui.py", line 553, in BusKillApp
LabelBase.register(
File "/usr/lib/python3/dist-packages/kivy/core/text/__init__.py", line 315, in register
raise IOError('File {0} not found'.format(font_type))
OSError: File fonts/RobotoMono-Regular.ttf not found
even if the font is available system-wide.
If you want to replicate the setup I have:
src/*
into /usr/share/buskill/
recursively./usr/bin/buskill
which contains the following:
#!/bin/bash
exec "/usr/bin/python3" "/usr/share/buskill/main.py" "$@"
exit "$?"
Then, you can delete the /usr/share/buskill/fonts/RobotoMono-Regular.tff
file and you'll get the above error.
I can reproduce the issue where the app doesn't load when the fonts file cannot be found.
However:
On a fresh install of buskill
on Debian 12, for example, we see can call kivy.core.text.LabelBase.get_system_fonts_dir(), and we get
['/usr/share/fonts', '/usr/share/fonts/cMap', '/usr/share/fonts/cmap', '/usr/share/fonts/woff', '/usr/share/fonts/woff/material-design-icons-iconfont', '/usr/share/fonts/woff/ebgaramond', '/usr/share/fonts/fonts-go', '/usr/share/fonts/type1', '/usr/share/fonts/type1/texlive-fonts-recommended', '/usr/share/fonts/type1/urw-base35', '/usr/share/fonts/eot', '/usr/share/fonts/eot/material-design-icons-iconfont', '/usr/share/fonts/X11', '/usr/share/fonts/X11/75dpi', '/usr/share/fonts/X11/encodings', '/usr/share/fonts/X11/encodings/large', '/usr/share/fonts/X11/Type1', '/usr/share/fonts/X11/util', '/usr/share/fonts/X11/100dpi', '/usr/share/fonts/X11/misc', '/usr/share/fonts/truetype', '/usr/share/fonts/truetype/lato', '/usr/share/fonts/truetype/andika', '/usr/share/fonts/truetype/croscore', '/usr/share/fonts/truetype/material-design-icons-iconfont', '/usr/share/fonts/truetype/font-awesome', '/usr/share/fonts/truetype/noto', '/usr/share/fonts/truetype/libreoffice', '/usr/share/fonts/truetype/freefont', '/usr/share/fonts/truetype/clear-sans', '/usr/share/fonts/truetype/charis', '/usr/share/fonts/truetype/crosextra', '/usr/share/fonts/truetype/gentiumplus', '/usr/share/fonts/truetype/droid', '/usr/share/fonts/truetype/gentiumplus-compact', '/usr/share/fonts/truetype/liberation2', '/usr/share/fonts/truetype/adf', '/usr/share/fonts/truetype/roboto', '/usr/share/fonts/truetype/roboto/unhinted', '/usr/share/fonts/truetype/roboto/unhinted/RobotoTTF', '/usr/share/fonts/truetype/liberation', '/usr/share/fonts/truetype/comfortaa', '/usr/share/fonts/truetype/paratype', '/usr/share/fonts/truetype/lyx', '/usr/share/fonts/truetype/open-sans', '/usr/share/fonts/truetype/dejavu', '/usr/share/fonts/truetype/gentium-basic', '/usr/share/fonts/truetype/quicksand', '/usr/share/fonts/truetype/ebgaramond', '/usr/share/fonts/truetype/gentium', '/usr/share/fonts/truetype/ancient-scripts', '/usr/share/fonts/opentype', '/usr/share/fonts/opentype/artemisia', '/usr/share/fonts/opentype/inter', '/usr/share/fonts/opentype/stix-word', '/usr/share/fonts/opentype/font-awesome', '/usr/share/fonts/opentype/stix', '/usr/share/fonts/opentype/freefont', '/usr/share/fonts/opentype/didot', '/usr/share/fonts/opentype/solomos', '/usr/share/fonts/opentype/junicode', '/usr/share/fonts/opentype/complutum', '/usr/share/fonts/opentype/linux-libertine', '/usr/share/fonts/opentype/asana-math', '/usr/share/fonts/opentype/lobstertwo', '/usr/share/fonts/opentype/cantarell', '/usr/share/fonts/opentype/lobster', '/usr/share/fonts/opentype/roboto', '/usr/share/fonts/opentype/roboto/slab', '/usr/share/fonts/opentype/olga', '/usr/share/fonts/opentype/comic-neue', '/usr/share/fonts/opentype/urw-base35', '/usr/share/fonts/opentype/ebgaramond', '/usr/share/fonts/opentype/neohellenic', '/usr/share/fonts/opentype/cabin', '/usr/local/share/fonts', '/usr/lib/python3/dist-packages/kivy/data/fonts']
The Roboto font is actually installed 3 times by the following packages:
user@disp9272:/usr$ dpkg -S /usr/share/buskill/fonts/Roboto-Regular.ttf
buskill: /usr/share/buskill/fonts/Roboto-Regular.ttf
user@disp9272:/usr$
user@disp9272:/usr$ dpkg -S /usr/lib/python3/dist-packages/kivy/data/fonts/Roboto-Regular.ttf
python3-kivy: /usr/lib/python3/dist-packages/kivy/data/fonts/Roboto-Regular.ttf
user@disp9272:/usr$
user@disp9272:/usr$ dpkg -S /usr/share/fonts/truetype/roboto/unhinted/RobotoTTF/Roboto-Regular.ttf
fonts-roboto-unhinted: /usr/share/fonts/truetype/roboto/unhinted/RobotoTTF/Roboto-Regular.ttf
user@disp9272:/usr$
So @fmarier you can probably remove the fonts-roboto
dependency on the buskill
package, since it's already installed by python3-kivy
. And, well, it's also being installed by this buskill
package too
user@disp9272:/usr$ ls /usr/lib/python3/dist-packages/kivy/data/fonts/
DejaVuSans.ttf Roboto-Bold.ttf RobotoMono-Regular.ttf
Roboto-BoldItalic.ttf Roboto-Italic.ttf Roboto-Regular.ttf
user@disp9272:/usr$
user@disp9272:/usr$ ls /usr/share/buskill/fonts/
MaterialIcons-Regular.ttf RobotoMono-Regular.ttf
Roboto-Medium.ttf Roboto-Regular.ttf
user@disp9272:/usr$
As for fallbacks to system fonts, I don't think that's possible in python/kivy.
The best I could do is find some random font in the fonts dir returned by kivy's LabelBase.get_system_fonts_dir()
, but I would have no way of knowing if the user, for example, had set some dyslexic-friendly font as their default system font
The default font in kivy appears to be, in fact, Roboto
user@disp9272:/usr$ ls /usr/lib/python3/dist-packages/kivy/data/fonts/
DejaVuSans.ttf Roboto-Bold.ttf RobotoMono-Regular.ttf
Roboto-BoldItalic.ttf Roboto-Italic.ttf Roboto-Regular.ttf
user@disp9272:/usr$
user@disp9272:/usr$ dpkg -S /usr/lib/python3/dist-packages/kivy/data/fonts/Roboto-Regular.ttf
python3-kivy: /usr/lib/python3/dist-packages/kivy/data/fonts/Roboto-Regular.ttf
user@disp9272:/usr$
# msg = "DEBUG: Default font = " + str(Config.get('kivy', 'default_font'))
# print( msg ); logger.debug( msg )
DEBUG: Default font = ['Roboto', 'data/fonts/Roboto-Regular.ttf', 'data/fonts/Roboto-Italic.ttf', 'data/fonts/Roboto-Bold.ttf', 'data/fonts/Roboto-BoldItalic.ttf']
The one thing that I'm doing that diverges is that I've used Roboto-Medium.ttf
in a few cases, which actually does not ship with python3-kivy
TODO: make this more robust by
buskill_gui.py
fails, then try to "find" Roboto-Medium.ttf
and the other font files in all the system font dirsyou can probably remove the
fonts-roboto
dependency on thebuskill
package, since it's already installed bypython3-kivy
. And, well, it's also being installed by thisbuskill
package too
Both of these Roboto-Regular.ttf
are symlinks to the font shipped by the fonts-roboto
package:
$ ls -l /usr/lib/python3/dist-packages/kivy/data/fonts/Roboto-Regular.ttf
lrwxrwxrwx - root root 10 déc 2023 /usr/lib/python3/dist-packages/kivy/data/fonts/Roboto-Regular.ttf -> ../../../../../../share/fonts/truetype/roboto/unhinted/RobotoTTF/Roboto-Regular.ttf
$ ls -l /usr/share/buskill/fonts/Roboto-Regular.ttf
lrwxrwxrwx - root root 8 sep 2023 /usr/share/buskill/fonts/Roboto-Regular.ttf -> ../../fonts/truetype/roboto/unhinted/RobotoTTF/Roboto-Regular.ttf
So there's only one copy of it on the system.
The one exception is RobotoMono-Regular.ttf
which until recently wasn't explicitly Open Source and hasn't yet been added to Debian (now that its licensing status has been clarified): https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=819273#99
I spent some time looking for how a user could specify their own custom font (eg for accessibility needs), but it's non-trivial.
There is no built-in "font picker" in kivy. I didn't find any examples from others online. The best I've got is a list of directories with font files, and then I can recursively poke through those for ttf
files.
I created a ComplexOption in the Settings screen for "font" and wrote some code to dynamically find all .ttf
files and add them as an option on the screen. The result is horrendous. A few iterations of tinkering slowed my computer down. Then it totally locked-up my computer and I had to restart the VM.
Most of these fonts are probably useless anyway. For example, I randomly picked-one and it was a font for the Tamil language. We need a way to par-down the list to be shorter.
TODO
For #2, I found some code on SE that uses the python module fonttools, but I actually liked this one better -- as it just uses the built-in module unicodedata
I found that, on my dev system, I have:
user@buskill:~/tmp/fonts$ cat font_test.py
#!/usr/bin/env python3
import os
font_dirs = ['/usr/share/fonts', '/usr/share/fonts/cMap', '/usr/share/fonts/cmap', '/usr/share/fonts/woff', '/usr/share/fonts/woff/material-design-icons-iconfont', '/usr/share/fonts/woff/ebgaramond', '/usr/share/fonts/fonts-go', '/usr/share/fonts/type1', '/usr/share/fonts/type1/texlive-fonts-recommended', '/usr/share/fonts/type1/urw-base35', '/usr/share/fonts/eot', '/usr/share/fonts/eot/material-design-icons-iconfont', '/usr/share/fonts/X11', '/usr/share/fonts/X11/75dpi', '/usr/share/fonts/X11/encodings', '/usr/share/fonts/X11/encodings/large', '/usr/share/fonts/X11/Type1', '/usr/share/fonts/X11/util', '/usr/share/fonts/X11/100dpi', '/usr/share/fonts/X11/misc', '/usr/share/fonts/truetype', '/usr/share/fonts/truetype/lato', '/usr/share/fonts/truetype/andika', '/usr/share/fonts/truetype/croscore', '/usr/share/fonts/truetype/material-design-icons-iconfont', '/usr/share/fonts/truetype/font-awesome', '/usr/share/fonts/truetype/noto', '/usr/share/fonts/truetype/libreoffice', '/usr/share/fonts/truetype/freefont', '/usr/share/fonts/truetype/clear-sans', '/usr/share/fonts/truetype/charis', '/usr/share/fonts/truetype/crosextra', '/usr/share/fonts/truetype/gentiumplus', '/usr/share/fonts/truetype/droid', '/usr/share/fonts/truetype/gentiumplus-compact', '/usr/share/fonts/truetype/liberation2', '/usr/share/fonts/truetype/adf', '/usr/share/fonts/truetype/roboto', '/usr/share/fonts/truetype/roboto/unhinted', '/usr/share/fonts/truetype/roboto/unhinted/RobotoTTF', '/usr/share/fonts/truetype/liberation', '/usr/share/fonts/truetype/comfortaa', '/usr/share/fonts/truetype/paratype', '/usr/share/fonts/truetype/lyx', '/usr/share/fonts/truetype/open-sans', '/usr/share/fonts/truetype/dejavu', '/usr/share/fonts/truetype/gentium-basic', '/usr/share/fonts/truetype/quicksand', '/usr/share/fonts/truetype/ebgaramond', '/usr/share/fonts/truetype/gentium', '/usr/share/fonts/truetype/ancient-scripts', '/usr/share/fonts/opentype', '/usr/share/fonts/opentype/artemisia', '/usr/share/fonts/opentype/inter', '/usr/share/fonts/opentype/stix-word', '/usr/share/fonts/opentype/font-awesome', '/usr/share/fonts/opentype/stix', '/usr/share/fonts/opentype/freefont', '/usr/share/fonts/opentype/didot', '/usr/share/fonts/opentype/solomos', '/usr/share/fonts/opentype/junicode', '/usr/share/fonts/opentype/complutum', '/usr/share/fonts/opentype/linux-libertine', '/usr/share/fonts/opentype/asana-math', '/usr/share/fonts/opentype/lobstertwo', '/usr/share/fonts/opentype/cantarell', '/usr/share/fonts/opentype/lobster', '/usr/share/fonts/opentype/roboto', '/usr/share/fonts/opentype/roboto/slab', '/usr/share/fonts/opentype/olga', '/usr/share/fonts/opentype/comic-neue', '/usr/share/fonts/opentype/urw-base35', '/usr/share/fonts/opentype/ebgaramond', '/usr/share/fonts/opentype/neohellenic', '/usr/share/fonts/opentype/cabin', '/usr/local/share/fonts', '/usr/lib/python3/dist-packages/kivy/data/fonts']
# find every font file in in all the font dirs
font_paths = []
for fonts_dir_path in font_dirs:
for root, dirs, files in os.walk(fonts_dir_path):
for file in files:
if file.lower().endswith(".ttf"):
font_paths.append(str(os.path.join(root, file)))
print( len(font_dirs) )
print( len(font_paths) )
user@buskill:~/tmp/fonts$
user@buskill:~/tmp/fonts$ ./font_test.py
77
6182
user@buskill:~/tmp/fonts$
I eliminated symlinks, but I still found the same number of fonts. Also, running this is actually very fast. The issue with kivy crashing the computer is just a kivy GUI issue with so many widgets being rendered on a screen. Perhaps it could be solved by a RecycleView. Or by going back to the normal non-complex OptionItem (if I can figure out how to populate it at runtime).
user@buskill:~/tmp/fonts$ tail -n 13 font_test.py
# find every font file in in all the font dirs
font_paths = []
for fonts_dir_path in font_dirs:
for root, dirs, files in os.walk(fonts_dir_path):
for file in files:
if file.lower().endswith(".ttf"):
file_path = os.path.join(root,file)
if not os.path.islink(file_path):
font_paths.append(str(file_path))
print( len(font_dirs) )
print( len(font_paths) )
user@buskill:~/tmp/fonts$
user@buskill:~/tmp/fonts$ time ./font_test.py
77
6182
real 0m0.043s
user 0m0.024s
sys 0m0.015s
user@buskill:~/tmp/fonts$
I opened an upstream feature request with the Kivy team to create a standard "FontPicker" SettingItem
This is already standard in other GUI frameworks, such as GTK and .NET
Last night I spent several hours trying to adapt our custom ComplexOptions class OptionsItem to be compatible with RecycleView (the positional arguments are an issue; I tried switching to kwargs, but it didn't work)
I also just now tried to load the 6,182 fonts into a normal option widget The normal built-in "option" widget handled the >6,000 entries better than my custom ComplexOption widget, but it still doesn't work:
1. It takes a few seconds to load
2. It doesn't scroll, so a user can only see the first ~10 fonts
TODO: try file picker (defaulting inside the font dir with the most number of TTF files found)
As for fallbacks to system fonts, I don't think that's possible in python/kivy.
Is there a way to simply not set the font (in case of an exception while looking for it)?
What I had in mind when initially filing this issue was that buskill should load even its font is missing. Yes, ideally, it should load whatever is defined as the default font for serif or sans serif on the system, but if that's too hard, then it should just pick an arbitrary font (ideally not picking anything and just letting the OS free to use whatever it wants). That would be better than not loading at all.
But maybe Kivy has a requirement to specify a font and there's no default or fallback?
If I don't set a font, then it will default to Roboto, which ships with kivy. If Roboto cannot be found, then it will throw an error.
(ideally not picking anything and just letting the OS free to use whatever it wants). That would be better than not loading at all.
A far as I can tell, there is no way to ask the OS to pick the font for us (at least not cross-platform let alone cross-DE). We could pick one arbitrarily, but then we risk picking a font that doesn't have glyphs for the characters we want.
If I don't set a font, then it will default to Roboto, which ships with kivy. If Roboto cannot be found, then it will throw an error.
That sounds like a reasonable solution then. If Roboto cannot be found in the buskill directory, then try again without setting the font. In that case, it will use Kivy's default (i.e. Roboto in the Kivy directory). If that fails, then that's not buskill's problem and it's instead a bug in the Kivy installation.
It sounds like the fact that there's no way to honor the OS defaults for fonts is a problem (or maybe feature request) with Kivy. If that ever gets fixed, then buskill will benefit from it automatically.
Yes. And I'd say the problem goes higher than kivy. It seems that python in-general should have some cross-platform way to fetch the OS default font.
I didn't have very good luck with the FilePicker. Namely the path
type in the Kivy Settings didn't allow much customization of the FilePicker widget -- such as being able to specify a filter
to only show *.ttf files.
I could have made a custom widget for this, but it also looked really bad and I figured it was likely just as much work to keep trying the RecycleView.
Indeed, I had much better luck today getting the fonts to appear in a recycle view. My latest commit displays >500 fonts (not sure why it's less than the 6,000 items before), and (with RecycleView) it loads near-instantaneous and has no lag when clicking around the screen.
This is just a proof of concept. I got the list of fonts to display, but I horribly broke the actual ability to click them and change the settings in the process. The biggest issue now is that my BusKillOptionItem()
class used to take positional arguments, but the way that RecycleView
is able to spawn custom widget is by passing it an array of dict()s with the values that will be passed into the widget as Kivy Properties.
(this was all very difficult to wrap my head around, and this example was instrumental in helping me get this far https://groups.google.com/g/kivy-users/c/4_xaX7xtL_s)
While I've managed to get ^ that working for the basic arguments (like icon, option value, description, etc), I'm not able to access them from within the object's functions itself -- namely __init__()
. This means at least two things are broken:
Config
object to get()
or set()
settings because the object property is None
within the object's __init()__
function.To address this, I've made a simplified example of this issue and posted it on SE:
I was successfully able to get the BusKillOptionItems()
created and clickable and saving to the Config
object last night.
I had to switch from using __init__()
to the kivy on_<property_name>()
function. In the case = on_manager()
. For more info, see my answer to the SE question linked-above
Unfortunately, I found some strange bug where if a user scrolls "up" at the top or "left" or "right" then it registers it like a click, so a user just scrolling through the list of fonts will change to the font under their cursor when they scroll at the "end". I've been fighting with this all day with no solution so-far. I created another SE question about this here:
I built the app with Debian 12, and the issue still occurs.
Unfortunately I just discovered that this issue occurs even on the dev
branch, so the RecycleView change was a red herring.
Yeah, I just downloaded v0.7.0
and confirmed that the scroll-becomes-a-click is also a bug on the Trigger setting.
I fixed the scroll-click bug by checking the value of the touch.button
inside the on_touch_up(self, touch)
function. More info:
In my latest commit, I have eliminated all references in the markup to Roboto fonts. Now fonts will just be rendered using the default_font
Setting that's originally setup by Kivy (which defaults to Roboto).
The user can now select a font in the GUI Settings menu, which updates default_font
directly, if set.
There's two exceptions to this where I specify a custom font:
I reference a custom font named "bkmono" in the text markup, which allows me to choose which mono font to use on-launch. By default, it will use RobotoMono.
The startup is also much more robust. If for some reason there's an issue finding the Roboto default fonts, BusKill will search all the Kivy-given font dirs recursively for the Roboto fonts and use whatever it finds as the default.
Of course, the app will still crash if it can't find any Roboto or Material Design Icons font on the system still, but what we have now is far more robust. And we have never had a report from a user indicating an issue with fonts.
Currently it requires 2 restarts of the app to actually apply the changes of the user's font to the app actually using it. I opened this SE question to address how to change all the widget's label's font face during runtime:
I've successfully gotten the app to update the font face of all widgets when the user exits the Settings menu, but now I'm struggling with the "reset" button again now that I've switched from using the buskill section's gui_font_face
setting, and now I'm using the built-in kivy section's default_font
setting.
Now that I'm deleting the kivy section's options when the reset button is pressed, I get a NoOptionError
when refresh_values()
tries to figure out the default_fonts
.
This could be easily fixed by updating my bulid_config()
's function with another Config.setdefaults('kivy', {...})
call, but then I'd have to hardcode the default_font
. And since Kivy has changed this value over-time, I think it's better to reference the actual kivy code to set this value for us.
The code for that is here:
https://github.com/kivy/kivy/blob/c492a33f8cf79e89ea7240690feb5f6d25b08389/kivy/config.py#L902-L908
...but I don't understand how to reference it because it's at the root of the file and not in any publicly-exposed method.
I asked this question on SE about this:
The latest commit to the font_setting branch now includes otf files (in addition to ttf files) for fonts, so users can now select a custom font in the GUI, including the Open Dyslexic fonts as mentioned in the OP
See the following screenshot of the BusKill App using the Open Dyslexic font
This has been merged into the dev
branch
TODO: test on macOS & Windows (blocked by #78)
I finally was able to hack together a MacOS build, and I found a bug. The app crashes immediately with failure to find mdicons.ttf
02:30:54,319 buskill_gui DEBUG DEBUG: Found 207 font files.
02:30:54,320 buskill_gui DEBUG DEBUG: Default font = ['Roboto', 'data/fonts/Roboto-Regular.ttf', 'data/fonts/Roboto-Italic.ttf', 'data/fonts/Roboto-Bold.ttf', 'data/fonts/Roboto-BoldItalic.ttf']
02:30:54,320 buskill_gui INFO INFO: Failed to load fonts (File fonts/RobotoMono-Regular.ttf not found)
02:30:54,321 buskill_gui DEBUG DEBUG: Found Roboto Mono ['/Volumes/buskill-1711842980/buskill-1711842980.app/Contents/Frameworks/kivy_install/data/fonts/RobotoMono-Regular.ttf']
02:30:54,321 buskill_gui DEBUG DEBUG: Found Material Icons []
02:30:54,322 buskill_gui WARNING WARNING: Failed to find fonts (list index out of range)
...
02:30:54,453 kivy INFO Base: Start application main loop
02:30:54,467 kivy INFO Base: Leaving application in progress...
02:30:54,470 kivy WARNING stderr: Traceback (most recent call last):
02:30:54,470 kivy WARNING stderr: File "main.py", line 150, in <module>
02:30:54,471 kivy WARNING stderr: BusKillApp( bk ).run()
02:30:54,471 kivy WARNING stderr: File "kivy/app.py", line 956, in run
02:30:54,472 kivy WARNING stderr: File "kivy/base.py", line 574, in runTouchApp
02:30:54,472 kivy WARNING stderr: File "kivy/base.py", line 339, in mainloop
02:30:54,472 kivy WARNING stderr: File "kivy/base.py", line 379, in idle
02:30:54,473 kivy WARNING stderr: File "kivy/clock.py", line 733, in tick
02:30:54,473 kivy WARNING stderr: File "kivy/clock.py", line 776, in post_idle
02:30:54,474 kivy WARNING stderr: File "kivy/_clock.pyx", line 620, in kivy._clock.CyClockBase._process_events
02:30:54,474 kivy WARNING stderr: File "kivy/_clock.pyx", line 653, in kivy._clock.CyClockBase._process_events
02:30:54,474 kivy WARNING stderr: File "kivy/_clock.pyx", line 649, in kivy._clock.CyClockBase._process_events
02:30:54,475 kivy WARNING stderr: File "kivy/_clock.pyx", line 218, in kivy._clock.ClockEvent.tick
02:30:54,475 kivy WARNING stderr: File "kivy/uix/label.py", line 425, in texture_update
02:30:54,475 kivy WARNING stderr: File "kivy/core/text/__init__.py", line 836, in refresh
02:30:54,476 kivy WARNING stderr: File "kivy/core/text/markup.py", line 141, in render
02:30:54,476 kivy WARNING stderr: File "kivy/core/text/markup.py", line 228, in _pre_render
02:30:54,476 kivy WARNING stderr: File "kivy/core/text/__init__.py", line 419, in resolve_font_name
02:30:54,477 kivy WARNING stderr: OSError: Label: File 'mdicons.ttf' not found
02:30:54,477 kivy WARNING stderr: [INFO/MainProcess] process shutting down
02:30:54,478 kivy WARNING stderr: [DEBUG/MainProcess] running all "atexit" finalizers with priority >= 0
02:30:54,478 kivy WARNING stderr: [DEBUG/MainProcess] running the remaining "atexit" finalizers
Somehow it looks like the Material Design font is no longer being included in our MacOS builds
From the logs we can see that our app's font dir is part of the list of font dirs returned by Kivy
19:45:11,487 buskill_gui DEBUG DEBUG: system_fonts_dirs:|['/Library/Fonts', '/System/Library/Fonts', '/System/Library/Fonts/Supplemental', '/Users/maltfield/Library/Fonts', '/Volumes/buskill-1711910000/buskill-1711910000.app/Contents/Frameworks/kivy_install/data/fonts'] font files.
But the dir doesn't have the MD font
maltfield@host ~ % ls /Volumes/buskill-1711910000/buskill-1711910000.app/Contents/Frameworks/kivy_install/data/fonts
DejaVuSans.ttf Roboto-BoldItalic.ttf Roboto-Regular.ttf
Roboto-Bold.ttf Roboto-Italic.ttf RobotoMono-Regular.ttf
maltfield@host ~ %
It looks like we already have the fonts here
/Volumes/buskill-1711910000/buskill-1711910000.app/Contents/Resources/fonts/MaterialIcons-Regular.ttf
It looks like the stable version of buskill_gui.py
had a commented-out line that prepended bk.EXE_DIR
.
After adding the bk.APP_DIR
to the font_dirs
list, I was finally able to open the app on MacOS.
Unfortunately, the hamburger menu icon is missing. And, f I slide the navbar from the left with the mouse gesture and click Settings
, then the app crashes claiming it can't find our buskill_settings.json
file.
20:49:01,612 kivy WARNING stderr: File "/Volumes/buskill-1711913377/buskill-1711
913377.app/Contents/Frameworks/buskill.kv", line 109, in <module>
20:49:01,613 kivy WARNING stderr: root.manager.current = 'settings'
20:49:01,613 kivy WARNING stderr: ^^^^^^^^^^^^^^^^^
20:49:01,613 kivy WARNING stderr: File "kivy/properties.pyx", line 520, in kivy.properties.Property.__set__
20:49:01,613 kivy WARNING stderr: File "kivy/properties.pyx", line 567, in kivy.properties.Property.set
20:49:01,614 kivy WARNING stderr: File "kivy/properties.pyx", line 606, in kivy.properties.Property._dispatch
20:49:01,614 kivy WARNING stderr: File "kivy/_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
20:49:01,614 kivy WARNING stderr: File "kivy/_event.pyx", line 1213, in kivy._event.EventObservers._dispatch
20:49:01,615 kivy WARNING stderr: File "kivy/uix/screenmanager.py", line 1063, in on_current
20:49:01,615 kivy WARNING stderr: File "kivy/uix/screenmanager.py", line 377, in start
20:49:01,615 kivy WARNING stderr: File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
20:49:01,615 kivy WARNING stderr: File "buskill_gui.py", line 966, in on_pre_enter
20:49:01,616 kivy WARNING stderr: s.add_json_panel( 'buskill', Config, os.path.join(self.bk.SRC_DIR, 'packages', 'buskill', 'settings_buskill.json') )
20:49:01,616 kivy WARNING stderr: File "kivy/uix/settings.py", line 1044, in add_json_panel
20:49:01,617 kivy WARNING stderr: File "kivy/uix/settings.py", line 1059, in create_json_panel
20:49:01,617 kivy WARNING stderr: FileNotFoundError: [Errno 2] No such file or directory: '/Volumes/buskill-1711913377/buskill-1711913377.app/Contents/MacOS/packages/buskill/settings_buskill.json'
The files are, in fact, present. And they're the same both for new builds and the last stable release (v0.7.0).
maltfield@5129 ~ % find /Volumes/buskill-* -name settings_buskill.json /Volumes/buskill-1711913377/buskill-1711913377.app/Contents/Resources/packages/buskill/settings_buskill.json
/Volumes/buskill-v0.7/buskill-v0.7.0.app/Contents/Resources/packages/buskill/settings_buskill.json
maltfield@5129 ~ %
It appears that this change somehow broke paths
ok, so the issue is that my old MacOS release had a bunch of symlinks from Contents/MacOS/ -> Contents/Resources/ but the new one does not
maltfield@host ~ % ls -lah /Volumes/buskill-1711913377/buskill-1711913377.app/Contents/MacOS
total 20440
drwxr-xr-x 4 maltfield staff 128B Mar 31 20:35 .
drwxr-xr-x 7 maltfield staff 224B Mar 31 20:35 ..
-rwxr-xr-x 1 maltfield staff 8.6M Mar 31 20:35 buskill
-r-x------ 1 maltfield staff 1.3M Mar 31 20:35 root_child_mac
maltfield@host ~ %
maltfield@host ~ % ls -lah /Volumes/buskill-v0.7/buskill-v0.7.0.app/Contents/MacOS
total 29512
drwxr-xr-x 46 maltfield staff 1.4K Jun 16 2023 .
drwxr-xr-x 7 maltfield staff 224B Jun 16 2023 ..
-rwxr-xr-x 1 maltfield staff 271K Jun 16 2023 FLAC
-rwxr-xr-x 1 maltfield staff 727K Jun 16 2023 FreeType
lrwxr-xr-x 1 maltfield staff 17B Jun 16 2023 KEYS -> ../Resources/KEYS
-rwxr-xr-x 1 maltfield staff 47K Jun 16 2023 Ogg
-rwxr-xr-x 1 maltfield staff 2.3M Jun 16 2023 Python
-rwxr-xr-x 1 maltfield staff 1.3M Jun 16 2023 SDL2
-rwxr-xr-x 1 maltfield staff 136K Jun 16 2023 SDL2_image
-rwxr-xr-x 1 maltfield staff 133K Jun 16 2023 SDL2_mixer
-rwxr-xr-x 1 maltfield staff 48K Jun 16 2023 SDL2_ttf
-rwxr-xr-x 1 maltfield staff 931K Jun 16 2023 Vorbis
lrwxr-xr-x 1 maltfield staff 24B Jun 16 2023 __pycache__ -> ../Resources/__pycache__
lrwxr-xr-x 1 maltfield staff 29B Jun 16 2023 base_library.zip -> ../Resources/base_library.zip
-rwxr-xr-x 1 maltfield staff 4.2M Jun 16 2023 buskill
lrwxr-xr-x 1 maltfield staff 33B Jun 16 2023 buskill-icon-150.png -> ../Resources/buskill-icon-150.png
lrwxr-xr-x 1 maltfield staff 30B Jun 16 2023 buskill-icon.icns -> ../Resources/buskill-icon.icns
lrwxr-xr-x 1 maltfield staff 23B Jun 16 2023 buskill.kv -> ../Resources/buskill.kv
lrwxr-xr-x 1 maltfield staff 27B Jun 16 2023 buskill_cli.py -> ../Resources/buskill_cli.py
lrwxr-xr-x 1 maltfield staff 27B Jun 16 2023 buskill_gui.py -> ../Resources/buskill_gui.py
lrwxr-xr-x 1 maltfield staff 31B Jun 16 2023 buskill_version.py -> ../Resources/buskill_version.py
lrwxr-xr-x 1 maltfield staff 20B Jun 16 2023 certifi -> ../Resources/certifi
lrwxr-xr-x 1 maltfield staff 21B Jun 16 2023 docutils -> ../Resources/docutils
lrwxr-xr-x 1 maltfield staff 18B Jun 16 2023 fonts -> ../Resources/fonts
lrwxr-xr-x 1 maltfield staff 16B Jun 16 2023 gpg -> ../Resources/gpg
lrwxr-xr-x 1 maltfield staff 19B Jun 16 2023 images -> ../Resources/images
drwxr-xr-x 9 maltfield staff 288B Jun 16 2023 kivy
lrwxr-xr-x 1 maltfield staff 25B Jun 16 2023 kivy_install -> ../Resources/kivy_install
drwxr-xr-x 51 maltfield staff 1.6K Jun 16 2023 lib-dynload
lrwxr-xr-x 1 maltfield staff 30B Jun 16 2023 libassuan.0.dylib -> ../Resources/libassuan.0.dylib
-rwxr-xr-x 1 maltfield staff 2.3M Jun 16 2023 libcrypto.1.1.dylib
lrwxr-xr-x 1 maltfield staff 31B Jun 16 2023 libgcrypt.20.dylib -> ../Resources/libgcrypt.20.dylib
lrwxr-xr-x 1 maltfield staff 33B Jun 16 2023 libgpg-error.0.dylib -> ../Resources/libgpg-error.0.dylib
lrwxr-xr-x 1 maltfield staff 28B Jun 16 2023 libintl.8.dylib -> ../Resources/libintl.8.dylib
lrwxr-xr-x 1 maltfield staff 22B Jun 16 2023 libintl.a -> ../Resources/libi
lrwxr-xr-x 1 maltfield staff 26B Jun 16 2023 libintl.dylib -> ../Resources/libintl.dylib
-rwxr-xr-x 1 maltfield staff 197K Jun 16 2023 liblzma.5.dylib
lrwxr-xr-x 1 maltfield staff 28B Jun 16 2023 libnpth.0.dylib -> ../Resources/libnpth.0.dylib
-rwxr-xr-x 1 maltfield staff 288K Jun 16 2023 libreadline.8.dylib
-rwxr-xr-x 1 maltfield staff 510K Jun 16 2023 libssl.1.1.dylib
lrwxr-xr-x 1 maltfield staff 29B Jun 16 2023 libusb-1.0.dylib -> ../Resources/libusb-1.0.dylib
lrwxr-xr-x 1 maltfield staff 20B Jun 16 2023 main.py -> ../Resources/main.py
-rwxr-xr-x 1 maltfield staff 226K Jun 16 2023 modplug
-rwxr-xr-x 1 maltfield staff 271K Jun 16 2023 mpg123
lrwxr-xr-x 1 maltfield staff 21B Jun 16 2023 packages -> ../Resources/packages
-r-x------ 1 maltfield staff 609K Jun 16 2023 root_child_mac
maltfield@host ~ %
Right now, it looks like the fonts are required for the UI to load. It would be great if the app would fallback to using whatever the defaults fonts are on the system when the
Roboto*
files are missing.Some dyslexic users for example choose to set their system fonts to https://opendyslexic.org/ and therefore it would be better on some systems to avoid overriding the user-selected fonts. (I would probably do this on Debian.)