racket / gui

Other
63 stars 78 forks source link

User can't launch DrRacket due to problem in `key-translate` #330

Closed soegaard closed 2 weeks ago

soegaard commented 3 months ago

From https://www.reddit.com/r/Racket/comments/1dwusoe/help_i_cant_use_the_drracket_app/

[lambduli](https://www.reddit.com/user/lambduli)
Hey everyone,

Today I installed the latest version `8.13` and it doesn't seem to work.

Here's what my setup is and what I tried:

I am on Apple MacBook Air with M1 chip. The latest OS.

The app from the launcher doesn't work. The icon bounces but then stops.

When I tried running it from the terminal I got this error:

integer->char: contract violation
  expected: valid-unicode-scalar-value?
  given: 55349
  context...:
   /Applications/Racket v8.13/share/pkgs/gui-lib/mred/private/wx/cocoa/key-translate.rkt:454:0: key-translate
   /Applications/Racket v8.13/share/pkgs/gui-lib/mred/private/wx/cocoa/key-translate.rkt:552:0
   body of "/Applications/Racket v8.13/share/pkgs/gui-lib/mred/private/wx/cocoa/key-translate.rkt"
   body of "/Applications/Racket v8.13/share/pkgs/gui-lib/mred/private/wx/platform.rkt"

   EDIT
   So it must be related to my layout. I have a custom keyboard layout with bunch of special symbols on it. When I switch to a simpler layout I can open DrRacket just fine. I think this might be a bug. I should probably open an issue.

The last line of key-translate is:

 (integer->char (ptr-ref output-chars _UniChar i))

The number 55349 from the error message falls outside the ranges accepted by integer->char. The accepted ranges are from 0 to D7FF and from E000 to 10FFFF.

The documentation from Apple says an array of UniChar is returned. UniChar stands for "UTF-16 code units".

A search for 55349 and UTF 16 confirms that 55349 is not a valid UTF 16 character.

Suggestion: We return some dummy value like #\space for integers from D800 to DFFF.

lambduli commented 3 months ago

Here is my keyboard layout that seems to be causing the issues. Code.keylayout.zip I had to zip it for GitHub. I will add screenshots in the next one.

lambduli commented 3 months ago

Screenshots of my layout.

No special keys pressed:

Screenshot 2024-07-06 at 23 40 58

Shift:

Screenshot 2024-07-06 at 23 41 06

Option key:

Screenshot 2024-07-06 at 23 41 13

Option key + Shift key:

Screenshot 2024-07-06 at 23 41 21

Caps lock key:

Screenshot 2024-07-06 at 23 41 32

Caps lock + Shift:

Screenshot 2024-07-06 at 23 41 38

Control key + option key:

Screenshot 2024-07-06 at 23 41 51
lambduli commented 3 months ago

I am on Apple MacBook Air Sonoma 14.5

soegaard commented 3 months ago

@lambduli Interesting layout - you've got to be a mathematician?

In the file gui-lib/mred/private/wx/cocoa/key-translate.rkt at line 495-496 we have:

(list->string (for/list ([i (in-range n)]) 
                       (integer->char (ptr-ref output-chars _UniChar i)))))

The problem is that your keyboard layout results in an integer (utf-16 character) 55349 outside the valid range.

Do you time to test the following? We simply ignore integers in the non-valid range:

(list->string (for/list ([i (in-range n)] #:when (not (<= #xD800 (ptr-ref output-chars _UniChar i) #xDFFF))) 
                       (integer->char (ptr-ref output-chars _UniChar i)))))
lambduli commented 3 months ago

I do stuff around type systems and type theory. I like to use these because it makes the formulae and all that more readable to me (m₁ reads much better than m1 or m_1 and such).

I'd be happy to test anything. I can't find the file in my installation so I at least tried to run the second expression but it gives me an error: ?: bad syntax in: #:when I kinda assumed that that's what you need me to do.

lambduli commented 3 months ago

Oh, sorry — found it. I just had to look up the error again.

soegaard commented 3 months ago

@lambduli You can find the file with this command:

mdfind key-translate.rkt | grep Applications

On my system the location is:

/Applications/Racket v8.12/share/pkgs/gui-lib/mred/private/wx/cocoa/key-translate.rkt

Open the file in a text editor and replace:

(list->string (for/list ([i (in-range n)]) 
                       (integer->char (ptr-ref output-chars _UniChar i)))))

with

(list->string (for/list ([i (in-range n)] #:when (not (<= #xD800 (ptr-ref output-chars _UniChar i) #xDFFF))) 
                       (integer->char (ptr-ref output-chars _UniChar i)))))
lambduli commented 3 months ago

It seems that it worked! I can open it from the launcher without having to switch to my simpler layout.

lambduli commented 3 months ago

@lambduli You can find the file with this command:

mdfind key-translate.rkt | grep Applications

On my system the location is:

/Applications/Racket v8.12/share/pkgs/gui-lib/mred/private/wx/cocoa/key-translate.rkt

Open the file in a text editor and replace:

(list->string (for/list ([i (in-range n)]) 
                       (integer->char (ptr-ref output-chars _UniChar i)))))

with

(list->string (for/list ([i (in-range n)] #:when (not (<= #xD800 (ptr-ref output-chars _UniChar i) #xDFFF))) 
                       (integer->char (ptr-ref output-chars _UniChar i)))))

Yeah you're right, I think my brain wasn't braining properly for a minute (it's quite late here). Thanks for your patience.

soegaard commented 3 months ago

It seems that it worked! I can open it from the launcher without having to switch to my simpler layout. Yeah you're right, I think my brain wasn't braining properly for a minute (it's quite late here). Great! Ditto (same time zone).

lambduli commented 3 months ago

Thanks for your help! This was a nice experience.

soegaard commented 2 months ago

@lambduli Thanks for the help.

I have committed a PR. The Github Action failed - not due to the PR - but because the Ubuntu version was bumped and now uses a newer glibc than expected by the build script (at least that's my current analysis).

mflatt commented 2 weeks ago

Fixed by #334