15 comments

  • userbinator 1 hour ago
    But at the moment when it lags the system switches from hardware cursor to software cursor (CGCursorIsDrawnInFramebuffer() goes from 0 to 1) so maybe that transition is stalled somehow on Macbook Neo.

    With the disclaimer that I have zero knowledge of the MacBook Neo hardware, but I do know a bit about GPUs in general (including having written some GPU-accelerated drivers for Windows and the associated cursor-handling code), I'm going to make a wild guess: this lag is caused by waiting for the GPU command queue to flush.

    As a bit of background information: the GPU is fed commands from a queue that the CPU writes to. These commands perform the drawing operations that the GPU is designed to accelerate. A hardware cursor is basically a small bitmap that can be positioned anywhere on the screen and moved around by simply updating position registers (which is normally done per mouse interrupt); the hardware draws it automatically. A software cursor is manually drawn by the graphics stack, which saves what was under it, draws the cursor, and then whenever it needs to be moved, writes the original data back, saves the data at the new position, and then draws the cursor there.

    Flushing the command queue is necessary when switching to a software cursor, or otherwise doing software writes to the framebuffer, because you need to wait for the GPU to finish drawing what it has queued, or it may end up drawing over what software wants to draw, including the cursor. Or worse, the command is a blit (e.g. scrolling a window) and you end up with remnants of the cursor at its previous position.

    • raphlinus 35 minutes ago
      This is plausible to me as well. A couple years ago we were trying to make dynamic memory allocation in Vello more robust and explored using async readback of a status buffer. In that case, the async task doesn't wake until the command buffer completes and signals a fence back to the CPU.

      Long story short, performance was disappointing and we abandoned the approach. It's easy to believe it's a real problem especially when there are other factors including GPU being clocked down to save power.

      Same caveat as parent, I have no direct knowledge of MacBook Neo or this specific issue.

    • jstanley 1 hour ago
      But wouldn't the software cursor operations also go in the queue? I don't see the problem.
      • userbinator 1 hour ago
        For something as small as a cursor they could be doing direct framebuffer writes.
    • nok22kon 1 hour ago
      how do hardware cursors work in a composited desktop?

      the cursor could just be another small rectangle texture you position on top of the other surfaces. there is no need to read the framebuffer/write into it, its just a z-stack of 3d surfaces now

    • bloqs 1 hour ago
      This was a really informative and interesting reply articulated in simple enough terms that I am now interested in GPUs, thanks
    • charcircuit 1 hour ago
      >A software cursor is manually drawn by the graphics stack, which saves what was under it, draws the cursor, and then whenever it needs to be moved, writes the original data back, saves the data at the new position, and then draws the cursor there.

      If a hardware layer is not being used the cursor layer will be treated like any other layer in the compositor. Modern compositors don't try and save and write pixels like that. It will just rerender it.

      >(which is normally done per mouse interrupt);

      It's normally done every frame the compositor makes.

      >or it may end up drawing over what software wants to draw

      The compositor composites everything at that will be shown on the next refresh of the display. Things don't indepently step on each others toes since it's just the compositor rendering and synchronizing all hardware layers (planes).

  • TheTon 2 hours ago
    I’m not sure what the bug is, but this is a terrible fix. What this is doing is forcing the WindowServer to composite the cursor rather than treat it as a hardware overlay. I suppose the issue must be pretty bad for OP if this helps, but … ugh.
    • nusl 1 hour ago
      Terrible fix but it's a fix that's minimally-invasive and addresses a bug that causes a disproportionate annoyance to the fix. I can imagine your cursor lagging is something that is extremely annoying over time.
      • nok22kon 59 minutes ago
        linux was plagued for a long time by lagging mouse cursor
        • koiueo 34 minutes ago
          I've been using Linux every day for the last 17 years, and that's the first time I'm hearing this.

          I'm genuinely surprised.

          The way you word it, it looks like a famous ubiquitous problem. Mind sharing any details?

          • jaapz 15 minutes ago
            I've also had computers with nvidia, amd (even back when it was still ATI) and intel gpu's, at least since 2006, and can't remember ever having an issue like this.

            Not saying it's not an issue, but there is such an incredible amount of hardware configurations that linux supports, so it's a bit weird to say that "linux" in general has suffered a bug like this.

          • dofm 25 minutes ago
            This was an Nvidia driver thing from the bad old days of Nvidia driver issues, I think.

            I have always had much cheaper Intel GPUs and not seen it (except in the very very old pre-GPU days, 30+ years ago with the odd badly behaved X app)

  • anotherpaul 2 hours ago
    This is such a nice fix but then you install it's set it up to launch on start and forget about it. 5 years later the bug has been fixed for 4 and I still have tho script record a random pixel every 10 seconds. Never know how to know that the hacky fix is no longer needed
    • nehal3m 2 hours ago
      You could just put it in your calendar. 'Check if that hacky bugfix at ~/.dirtyhack.sh is still required with chmod -x ~/.dirtyhack.sh'
      • joxdosba 1 hour ago
        Or do a counter with read n<.hackycounter;echo $[n+1]>.hackycounter

        When the counter hits e.g. 200, spam the user with notifications.

  • zx8080 55 minutes ago
    Round rect corners are to blame?

    The root cause for the issue is probably (I'm not an Apple developer) due to huge round rectangles on the window shape corners. Rendering the window with the corners would include rendering whatever other windows and widgets under the window. (Which will have a lag and some more operations with transparency, which the developers probably want to avoid - while I'm not sure about this part).

  • m132 3 hours ago
    Steve turning in his grave
    • InsideOutSanta 2 hours ago
      Relevant quote from https://www.folklore.org/Shut_Up.html:

      We showed [Gates] how the Macintosh mouse cursor moved smoothly, in a flicker-free fashion.

      "What kind of hardware do you use to draw the cursor?", he asked. Many current personal computers had special hardware to draw small bitmaps called "sprites", and he thought we might be doing something similar.

      • Stitch4223 1 hour ago
        This quote from 1981 stresses that taking away a responsive cursor is the most arrogant and disrespectful bug.

        The audacity of developers to restart the discussion whether the mouse should follow user input induces rage on so many levels.

        • InsideOutSanta 37 minutes ago
          Yeah, the cursor is your most direct embodiment in the computer. Messing with it is like somebody pushing your arm when you're trying to cut tomatoes. It's a major determinant in how good it feels to use a computer (and whether you cut your fingers).

          But there were a lot of things we learned in the 80s and 90s that we have largely forgotten today, like "make clickable things look clickable" and "don't use Yes and No as button labels" and "active windows should look different from inactive windows."

    • flukas88 2 hours ago
      [flagged]
  • xnx 2 hours ago
    Sometimes the cure is worse than the disease.
  • vardump 58 minutes ago
    Embedded Swift in a script. That seems like a useful concept for small scripts on macOS. I will definitely steal this idea.
  • zuhsetaqi 1 hour ago
    Does anyone know if this is fixed in macOS 27?
  • inigyou 2 hours ago
    What's with "guard !foo else return" instead of "if foo return", is that just how Swift is written?
    • NobodyNada 2 hours ago
      guard is an inverted if statement, with the additional requirement that the branch must exit the parent scope. It's useful sometimes for readability, particularly for avoiding the "pyramid of doom" when you have a lot of preconditions that need to be checked:

          if fooOK 
              if barOK {
                  if bazOK {
                      // do something
                  }
              }
          }
      
      can be written as:

          guard fooOK else { return }
          guard barOK else { return }
          guard bazOK else { return }
          // do something
      
      Obviously there are other options (like writing a negated if), but sometimes guard is more readable. It's a style thing.

      The more important use case for guard is that 'guard let' statements can pattern-match and introduce bindings that are valid for the rest of the scope:

          guard let foo = someOptional else { return }
          print(foo);
      
      This is useful enough that Rust copied it in the form of 'let ... else {}' statements (but did not bring over boolean guard statements).
    • wwalexander 1 hour ago
      guard has two advantages: the compiler ensures that you exit the current scope if the condition does not hold (via return, break, continue, etc), and bindings established in the guard clause (e.g. let foo = optionalBar) remaining in scope after the guard block, rather than inside it like an if block.
  • swiftcoder 2 hours ago
    Is the fix working because it forces the WindowServer to do a full composition of the cursor overlay, or just because it prevents the system from throttling down into a lower power mode?
  • adithyassekhar 1 hour ago
    The duality of TheTon’s and anotherpaul’s comments.
  • alvaniss 1 hour ago
    ah yes, the famous mac "Just works" OS
    • flyingshelf 8 minutes ago
      That was like 20 years ago. My computer insists on downloading gigabytes of videos at random (correction: specifically when I use the hotspot) because maybe I have a video screensaver enabled.

      I had to set up a daemon to kill the downloader every 10 seconds.

    • koiueo 30 minutes ago
      What's the big deal?

      It's just a simple one-liner

      curl github.com/trustworthyguy/fix_everything | sh

      And it all works. Not like recompiling entire kernel to play an mp3.

      /s obviously