Skip to content

AI told me this is a bug? #186

Closed
Closed

Description

@WREQI

This is the current behavior of Perry's perry/ui TextField where macOS input method "pre-editing/candidate hints (marked text)" display is incomplete: Chinese input can be committed normally, but during the input process, the system's "underline pre-editing + candidate hint floating window/tab" does not display as fully as in native apps

Activity

  1. added
    bugConfirmed defect or regression
    on Apr 25, 2026
  2. WREQI commented on Apr 25, 2026

    @WREQI
    Author
    Image
  3. WREQI commented on Apr 25, 2026

    @WREQI
    Author
    Image
  4. WREQI commented on Apr 25, 2026

    @WREQI
    Author

    Figure 1 shows the development process, while Figure 2 shows a normal prompt when entering text into any input box

  5. WREQI commented on Apr 25, 2026

    @WREQI
    Author
  6. proggeramlug commented on Apr 25, 2026

    @proggeramlug
    Contributor

    Thanks for the detailed report and the uUhat repro — that helped a lot. I tried to reproduce on my end and want to compare notes before fixing, because what I see doesn't match Figure 1.

    My setup

    • macOS 26.4 (Apple Silicon)
    • SCIM Pinyin (com.apple.inputmethod.SCIM.ITABC) — Apple's built-in
    • Tested both your pre-built uUhat binary AND a fresh rebuild against current main (v0.5.224)

    What I see
    With the same wen input that produced your Figure 1, the candidate window shows up correctly with all 8 candidates (1.问 2.文 3.闻 4.👃 5.温 6.纹 7.稳 8.吻) and the paging chevron — both in your search TextField (popup appears below the field) and in the message TextArea (popup appears below the caret line, inside the view body — matches native NSTextView behavior).

    I also tested a longer sequence (nihao) and it shows segmented marked text plus 1.你好 2.👋 3.你好吗 4.你号 ... correctly.

    (Happy to attach side-by-side screenshots — they look indistinguishable from your Figure 2.)

    Two hypotheses, can you help me narrow down?

    1. Crop: Figure 1 is 958×218 — just tall enough to show the marked-text line. On macOS the candidate panel appears below the caret line, which inside a multi-line TextArea falls within the view's bounds (not below the whole view). If your screenshot was cropped right after the marked text, the popup might be just outside the visible region. A wider screenshot (say 300 px taller) would settle this.

    2. Different IME: I only tested Apple SCIM. If you're on Sogou (搜狗), Rime, Squirrel, or another third-party IME, they sometimes use stricter coordinate queries (firstRectForCharacterRange:actualRange:) and a perry/ui bug there is plausible. Apple SCIM is more forgiving.

    Could you share:

    1. sw_vers output (macOS version)
    2. Which input method — Apple SCIM Pinyin, or third-party? If third-party, which one + version
    3. A wider screenshot showing ~200-300 px below the marked text — full window if possible
    4. Whether the issue happens on the small TextField (the search box at the top of uUhat) too, or only on the TextArea (the message input at the bottom)

    If it's third-party IME, I'll set that up here and trace the IME-protocol calls. With Apple SCIM I just can't reproduce on main.

  7. WREQI commented on Apr 25, 2026

    @WREQI
    Author

    At present, it is still very difficult to develop applications using this library with AI, possibly due to insufficient data and insufficient knowledge of AI big models

  8. WREQI commented on Apr 25, 2026

    @WREQI
    Author

    Thanks for the detailed report and the uUhat repro — that helped a lot. I tried to reproduce on my end and want to compare notes before fixing, because what I see doesn't match Figure 1.

    My setup

    • macOS 26.4 (Apple Silicon)
    • SCIM Pinyin () — Apple's built-incom.apple.inputmethod.SCIM.ITABC
    • Tested both your pre-built binary AND a fresh rebuild against current (v0.5.224)uUhat``main

    What I see With the same input that produced your Figure 1, the candidate window shows up correctly with all 8 candidates (1.问 2.文 3.闻 4.👃 5.温 6.纹 7.稳 8.吻) and the paging chevron — both in your search (popup appears below the field) and in the message (popup appears below the caret line, inside the view body — matches native behavior).wen``TextField``TextArea``NSTextView

    I also tested a longer sequence () and it shows segmented marked text plus correctly.nihao``1.你好 2.👋 3.你好吗 4.你号 ...

    (Happy to attach side-by-side screenshots — they look indistinguishable from your Figure 2.)

    Two hypotheses, can you help me narrow down?

    1. Crop: Figure 1 is 958×218 — just tall enough to show the marked-text line. On macOS the candidate panel appears below the caret line, which inside a multi-line falls within the view's bounds (not below the whole view). If your screenshot was cropped right after the marked text, the popup might be just outside the visible region. A wider screenshot (say 300 px taller) would settle this.TextArea
    2. Different IME: I only tested Apple SCIM. If you're on Sogou (搜狗), Rime, Squirrel, or another third-party IME, they sometimes use stricter coordinate queries () and a perry/ui bug there is plausible. Apple SCIM is more forgiving.firstRectForCharacterRange:actualRange:

    Could you share:

    1. sw_vers output (macOS version)
    2. Which input method — Apple SCIM Pinyin, or third-party? If third-party, which one + version
    3. A wider screenshot showing ~200-300 px below the marked text — full window if possible
    4. Whether the issue happens on the small (the search box at the top of ) too, or only on the (the message input at the bottom)TextField``uUhat``TextArea

    If it's third-party IME, I'll set that up here and trace the IME-protocol calls. With Apple SCIM I just can't reproduce on .main
    I am using the input method that comes with my Apple laptop

    Image Image Image
  9. WREQI commented on Apr 25, 2026

    @WREQI
    Author

    I am using the input method that comes with my Apple laptopmain

    @

  10. proggeramlug commented on Apr 25, 2026

    @proggeramlug
    Contributor

    Thanks for confirming Apple's built-in IME, macOS Tahoe 26.4.1, M5 — that helps narrow it.

    I tried to reproduce on my end across every environment variant I can flip:

    • macOS 26.4 (one point release behind you), Apple Silicon (not M5)
    • Light mode AND dark mode
    • Single built-in display AND with secondary monitors
    • Large centered window AND small window with input near the screen edge
    • Both a 20-line minimal repro AND your own pre-built uUhat binary

    In every case the candidate panel shows up correctly with all 8 candidates. So the failure is bound to either (a) macOS 26.4.1 specifically, (b) the M5 chip, or (c) something in your entry/desktop.ts (which isn't in the public repo, so I can't inspect it).

    Could you run this 20-line minimal repro on your machine? It'll tell us which of (a)/(b)/(c) it is.

    Save as ime_min.ts:

    import { App, TextField, TextArea, VStack, Text, State,
             textSetFontSize, widgetSetWidth, widgetSetHeight } from "perry/ui";
    
    const fieldText = State("");
    const areaText  = State("");
    
    const lbl1 = Text("TextField (one-line):"); textSetFontSize(lbl1, 12);
    const tf   = TextField("type here", (v: string) => fieldText.set(v));
    widgetSetWidth(tf, 480);
    
    const lbl2 = Text("TextArea (multi-line):"); textSetFontSize(lbl2, 12);
    const ta   = TextArea("type here", (v: string) => areaText.set(v));
    widgetSetWidth(ta, 480); widgetSetHeight(ta, 120);
    
    App({ title: "IME min repro #186", width: 540, height: 280,
          body: VStack(12, [lbl1, tf, lbl2, ta]) });

    Compile + run:

    perry compile ime_min.ts -o ime_min && ./ime_min
    

    Then with Pinyin active, click the TextArea (multi-line), type wen, and screenshot.

    Three possible outcomes:

    1. Candidate window also missing in this minimal repro → it's macOS 26.4.1 + M5, not Perry. We'll dig into the IME-protocol layer.
    2. Candidate window appears here but not in uUhat → something in your entry/desktop.ts setup is breaking the input context. Sharing that file (or the relevant App({...}) block) would unblock the diagnosis.
    3. Both work in this minimal repro AND in uUhat after cargo update && perry compile → maybe a stale build artifact. Worth ruling out.

    Side note: I noticed error messaging the mach p…LoopWakeUpReliable in your terminal output. Probably unrelated noise (it's an IOPMAssertion log), but if the candidate window is missing AND that error fires every time you type, let me know — that combination would point at a different angle.

  11. WREQI commented on Apr 25, 2026

    @WREQI
    Author
    Image Image I tested it, and your minimum test is correct
  12. proggeramlug commented on Apr 25, 2026

    @proggeramlug
    Contributor

    Perfect — that rules out macOS 26.4.1 + M5 entirely, and confirms perry/ui TextArea + IME works correctly in isolation on your exact hardware. So the bug is bound to something specific in your uUhat setup.

    The next step is figuring out which part of your real app breaks it. Could you incrementally evolve the minimal repro toward your real uUhat shape and report which step kills the candidate window? Stop as soon as it breaks — that's the trigger.

    Take the working ime_min.ts from the previous test and modify the TextArea step by step. After each step, recompile + run + type wen into the TextArea and check if the candidate window still appears:

    Step 1 — add corner radius + insets (matches your setCornerRadius(field, 6); widgetSetEdgeInsets(field, 10, 10, 10, 10)):

    import { ..., setCornerRadius, widgetSetEdgeInsets } from "perry/ui";
    // after creating ta:
    setCornerRadius(ta, 6);
    widgetSetEdgeInsets(ta, 10, 10, 10, 10);

    Step 2 — wrap the TextArea in an HStack with a Button beside it (matches your inputRow = HStack(8, [field, sendBtn])):

    import { ..., HStack, Button, buttonSetBordered } from "perry/ui";
    const sendBtn = Button("发送", () => {});
    buttonSetBordered(sendBtn, 1);
    const inputRow = HStack(8, [ta, sendBtn]);
    // then put inputRow in the body instead of ta

    Step 3 — add a ForEach driven by State above the input (matches your chat list):

    import { ..., ForEach } from "perry/ui";
    const items = State<number[]>([1, 2, 3, 4, 5]);
    const list = VStack(0, [ForEach(State(5), (i: number) => Text(`row ${i}`))]);
    // body becomes: VStack(12, [list, lbl2, inputRow])

    Step 4 — share your entry/desktop.ts (or the relevant App({...}) block). It's not in the public repo so I can't see what's different about your top-level setup.

    If any of steps 1-3 break the candidate window, that's the smoking gun and we have a fix target. If they all work, step 4 is the answer — your app-level setup is doing something unusual.

  13. WREQI commented on Apr 26, 2026

    @WREQI
    Author

    Yesterday didn't work, but today I opened and ran it, and it worked fine on its own. It's really a strange problem.

  14. proggeramlug commented on Apr 26, 2026

    @proggeramlug
    Contributor

    @WREQI I did release a new version a few hours ago that might have "accidentally" fixed it.

    I'm closing this for now but I'll keep this in memory in case anything like this pops up again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regression

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions