Skip to content
New issue

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

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

Already on GitHub? # to your account

Rewrite the xcursor caching code #3745

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

psychon
Copy link
Member

@psychon psychon commented Dec 4, 2022

Previously, the cache for xcursors consisted of a static array. We had a hardcoded list of supported cursor names and each one got assigned a position in this array. This hardcoded list means that one cannot simply use whatever cursor a cursor theme happens to provide, since the name needs to be in our list.

In this commit, the code is rewritten. Instead of a hardcoded list, a sorted array is now used as the cache, as provided by the BARRAY code from common/util.h. The array is sorted by the name of the cursor.

This change implies an API change for the xcursor code. Previously, one had to first translate a cursor name into a cache index (xcursor_font_fromstr()) and could then use this to actually get the cursor (xcursor_new()). With this commit, xcursor_new() is the only function provided by the cursor code and it directly gets a string as argument.

Signed-off-by: Uli Schlachter psychon@znc.in


This PR is related to #3737. I am 80% sure that this PR implements (half of) that feature request by making it possible to use arbitrary cursors, as long as xcb-util-cursor can load a cursor by that name.

@akinokonomi Are you in a position to test this? (=Can you build awesome from a git branch and verify whether this does what you want?)

Personally, I only started awesome via tests/run.sh /dev/null and started xterm from the menu. The "waiting for startup" cursor briefly appeared. Nothing more was tested.

Previously, the cache for xcursors consisted of a static array. We had a
hardcoded list of supported cursor names and each one got assigned a
position in this array. This hardcoded list means that one cannot simply
use whatever cursor a cursor theme happens to provide, since the name
needs to be in our list.

In this commit, the code is rewritten. Instead of a hardcoded list, a
sorted array is now used as the cache, as provided by the BARRAY code
from common/util.h. The array is sorted by the name of the cursor.

This change implies an API change for the xcursor code. Previously, one
had to first translate a cursor name into a cache index
(xcursor_font_fromstr()) and could then use this to actually get the
cursor (xcursor_new()). With this commit, xcursor_new() is the only
function provided by the cursor code and it directly gets a string as
argument.

Signed-off-by: Uli Schlachter <psychon@znc.in>
@codecov
Copy link

codecov bot commented Dec 4, 2022

Codecov Report

Merging #3745 (ec3901a) into master (e281fa3) will increase coverage by 0.00%.
The diff coverage is 90.00%.

@@           Coverage Diff           @@
##           master    #3745   +/-   ##
=======================================
  Coverage   90.99%   90.99%           
=======================================
  Files         900      900           
  Lines       57499    57498    -1     
=======================================
  Hits        52319    52319           
+ Misses       5180     5179    -1     
Flag Coverage Δ
gcov 90.99% <90.00%> (+<0.01%) ⬆️
luacov 93.70% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
globalconf.h 100.00% <ø> (ø)
objects/drawin.c 88.27% <33.33%> (+0.32%) ⬆️
common/xcursor.c 100.00% <100.00%> (ø)
mousegrabber.c 80.64% <100.00%> (-0.61%) ⬇️
root.c 87.84% <100.00%> (ø)
lib/wibox/widget/imagebox.lua 95.53% <0.00%> (-0.90%) ⬇️
lib/awful/widget/layoutlist.lua 89.28% <0.00%> (-0.60%) ⬇️
tests/test-screenshot.lua 97.21% <0.00%> (-0.35%) ⬇️
spawn.c 86.16% <0.00%> (+0.06%) ⬆️
tests/test-input-binding.lua 99.50% <0.00%> (+2.00%) ⬆️

@psychon
Copy link
Member Author

psychon commented Dec 4, 2022

Nothing more was tested.

I had an idea!

diff --git a/awesomerc.lua b/awesomerc.lua
index c598a3e08..a5cad2eed 100644
--- a/awesomerc.lua
+++ b/awesomerc.lua
@@ -191,6 +191,7 @@ screen.connect_signal("request::desktop_decoration", function(s)
         position = "top",
         screen   = s,
         -- @DOC_SETUP_WIDGETS@
+        cursor = "foobar",
         widget   = {
             layout = wibox.layout.align.horizontal,
             { -- Left widgets

results in

2022-12-04 09:38:34 W: awesome: xerror:1058: X error: request=CreateGlyphCursor (major 94, minor 0), error=BadValue (2)
2022-12-04 09:38:34 W: awesome: xerror:1058: X error: request=ChangeWindowAttributes (major 2, minor 0), error=BadCursor (6)
2022-12-04 09:38:34 W: awesome: xerror:1058: X error: request=ChangeWindowAttributes (major 2, minor 0), error=BadCursor (6)

Checking ls /usr/share/icons/*/cursors, I found dot_box_mask. That one works (and IMO looks confusing, but whatever...).

Will investigate the above X11 errors and report back.

Edit: Excerpt from xtrace output:

000:<:0011: 20: Request(45): OpenFont fid=0x00600001 name='cursor'
000:<:0139: 32: Request(94): CreateGlyphCursor cid=0x00600011 source-font=0x00600001 mask-font=0x00600001 source-char=0xffff mask-char=0x0000 fore-red=0x0000 fore-green=0x0000 fore-blue=0x0000 back-red=0xffff back-green=0xffff back-blue=0xffff
000:>:0139:Error 2=Value: major=94, minor=0, bad=0x0000ffff, seq=0139

Looks a bit more like a problem in xcb-util-cursor...

Edit: Now this looks like a mis-compilation?! We are running this code: https://gitlab.freedesktop.org/xorg/lib/libxcb-cursor/-/blob/3d7e713e85af18d7e52cafdc9d20a2715048dee7/cursor/load_cursor.c#L209-211
gdb says:

(gdb) finish
Run till exit from #0  cursor_shape_to_id (name=name@entry=0x5555555f5ad8 "foobar") at shape_to_id.gperf:84
0x00007ffff7a030e5 in xcb_cursor_load_cursor (c=c@entry=0x5555555c6610, name=name@entry=0x5555555f5ad8 "foobar") at load_cursor.c:209
209	            core_char = cursor_shape_to_id(name);
1: fd = <optimized out>
2: core_char = -1
Value returned is $8 = -1
(gdb) next
211	        cid = xcb_generate_id(c->conn);
1: fd = <optimized out>
2: core_char = -1

You see that cursor_shape_to_id() returned -1 and that core_char was set to -1. Yet, if (core_char == -1) return XCB_NONE; is not executed and instead a cursor from the "cursor" font is created. The rest is -1 converted to uint16_t...

Edit: And if I ask gdb to disassemble the code, I get this:

   0x00007ffff7a030e0 <+64>:	call   0x7ffff7a02650 <cursor_shape_to_id>
=> 0x00007ffff7a030e5 <+69>:	mov    %eax,-0x48(%rbp)
   0x00007ffff7a030e8 <+72>:	mov    (%rbx),%rdi
   0x00007ffff7a030eb <+75>:	call   0x7ffff7a01990 <xcb_generate_id@plt>

The check against -1 seems to be quite gone.

@psychon
Copy link
Member Author

psychon commented Dec 4, 2022

Ahhh, debian is using an old (ancient?) version of libxcb-cursor. The bug I found above was fixed 7 years ago: https://gitlab.freedesktop.org/xorg/lib/libxcb-cursor/-/commit/cf26479ece9ab9e04616bc10ba674d88a284e5b0

Edit: Reported as https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1025409

@akinokonomi
Copy link

Are you in a position to test this? (=Can you build awesome from a git branch and verify whether this does what you want?)

Certainly.

Compiled against LuaJIT 2.1 beta3, xcb-util-cursor 0.1.4.

Everything looks good. Did not notice any issue so far.

And after changing the startup cursor like this:

diff --git a/lib/awful/startup_notification.lua b/lib/awful/startup_notification.lua
index 9bc95236c..45ad9c639 100644
--- a/lib/awful/startup_notification.lua
+++ b/lib/awful/startup_notification.lua
@@ -18,7 +18,7 @@ local beautiful = require("beautiful")
 
 local app_starting = {}
 
-local cursor_waiting = "watch"
+local cursor_waiting = "left_ptr_watch"
 
 --- Show busy mouse cursor during spawn.
 -- @beautiful beautiful.enable_spawn_cursor

It does exactly what I want. Thank you!

Please let me know if I have to test something else.

@psychon
Copy link
Member Author

psychon commented Dec 4, 2022

Thanks a lot for testing this!

Copy link
Member

@Aire-One Aire-One left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was a mildly challenging but interesting review since I haven't had read common/array.h before. Thank you, @psychon, for this PR.

@psychon
Copy link
Member Author

psychon commented Dec 9, 2022

since I haven't had read common/array.h before.

Don't go there! It is dark magic that wasn't touched in ages! ;-)

But yeah, that file is actually used a lot in the C code to manage lists, but I guess one seldomly has to actually interact with this file.

(Latest commit is from 2016 by yours truly and it removes a feature. Before that, there were one commit in 2015, 2014, 2011, 2010. I guess this must mean that this is good code that doesn't need any touching...)

@actionless
Copy link
Member

this would require manual merging because of codecov

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants