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.
The display controller and render device are completely distinct logical devices, even though they are often grouped in a "GPU". On mobile architectures they are quite far separated, leading to annoying problems surrounding what we on Linux call "split drm devices".
Updating plane properties such as to move the cursor plane around or disable it would by itself not block on render activities, as they are completely distinct blocks.
The render hardware could be powered down, but I doubt powering it up and compositing the cursor would take long enough to complete to cause any noticable lag.
Under the Linux APIs, updates to the display controller are done through KMS atomic commits, and one mistake you could do display-server side would be to provide a fence in this atomic commit that the scheduler will use to wait on long-running GPU work before using the provided graphics buffers. Under this API, none of the changes - including mouse movements - would then be applied until that fence is signalled. Changing plane associations can lead to resource reallocations that can be a bit heavy.
Not sure if the kernel driver in macOS works anything remotely similar to this, and the driver could also just be dumb and block on unrelated things ("let's just wait another vblank to see this apply....", "as we only need one plane now let's power down hardware and wait for that to settle..."). It could also just be windowserver that waits for work to finish on its own, not providing any cursor updates in the meantime.
The reality is that it will take reverse engineering or looking at actual code to know what's going on.
No, the cursor just uses an overlay plane, and mobile architectures usually have far more planes (sometimes even an arbitrarily configurable amount), and more flexible hardware compositioning overall than desktop GPUs for efficiency reasons.
EDIT: Also note that there is nothing new with the Neo here, as all Macs since the M1 have used the same chip architecture as the iPhone.
Desktop GPU designs did not focus on tiny efficiency gains, and often only has a primary plane, a single overlay plane (for e.g., a video), and a dedicated cursor plane. Some even have to share a single overlay plane between all connected displays. It's a recent thing for desktop GPUs to get more flexible in this area, in part to improve laptop battery life in the cases where the laptop is almost entirely idle.
(For those unaware, a "plane" here is the entity in the display controller you configure to show a rendered graphics buffer, in a particular location and with particular transforms. You commonly have one plane that just covers the whole screen, and then sometimes put dynamic content on top in other planes so you can avoid having to redraw the main buffer when smaller bits of it change, like a video player or cursor. You could also e.g., scroll by rendering an entire document in advance and then move the plane around to reveal parts of it.)
> 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
Do modern machines still have custom hardware for cursors? That would surprise me, as a GPU can easily blit a small cursor on top of whatever gets drawn.
The cursor plane is the way to "easily blit a small cursor on top of whatever gets drawn". If the cursor was drawn on the primary plane, the primary plane would need to be redrawn (expensive!) or repaired (messy!) to change the cursor position.
Modern GPUs usually have multiple command queues, at least one for application use (often separate queues for rendering and compute) and one for OS use. There's a good chance that this wasn't implemented on a chip intended for a phone.
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.
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
AFAIK, they work just like in a non-composited desktop.
The problem with rendering the cursor into the primary plane is that, often, only the cursor changes, and you'd have to re-render the whole plane that contains the cursor. That is easily doable for modern hardware, but bad for power consumption and may also be higher latency. (The latency aspect gets interesting when dragging something on the primary plane - I think most compositors temporarily disable the hardware cursor in order to keep cursor and dragged object in sync.)
>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).
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.
Reminds me of a fix I wrote a decade ago. My Laptop would sometimes start emitting a high frequency whine when on battery. I figured out it only happened when the CPU went into performance states lower than P2 for power saving.
So I wrote a bash script that auto-started on battery mode and then calculated a hash every few seconds. Boom, whine solved. Terrible fix, but I never measured how much battery it cost me, so it was... fine.
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.
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.
not necessarily ubiquitous, but you can encounter some issues with "lagging cursor" even today, if you use standard raspbian for example
> usbhid.mousepoll=0
> to /boot/cmdline.txt
> This option was implemented to enforce a mouse polling rate of 62.5Hz which dramatically reduced the XWindow event system update rate in certain circumstances (oddball or "performance" mice can have update rates of 1000Hz, which is silly).
There was a time when it was quite bad, especially if using Wayland and under heavy CPU or I/O loads. I think this has mostly been solved now, but I do recall getting frustrated with the switch to Wayland because of it.
Crazy this would be the case when the MacOS cursor has been buttery smooth and only ever lags if the entire system is about to go down even on 800Mhz G4 Titanium Powerbook this was the behavior.
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
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.
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."
SGIs and Suns had overlay planes just for that. In fact SGI 4Sight would draw the popup menus in the overlay plane, too, since reading back the color framebuffer to draw cursors or perform xor highlighting or restoring the background after popping down menus was extremely expensive with that hardware.
Sun's framebuffers with 8 bit color + 1 bit monochrome + 1 bit enable (like the cgfour / GX aka Lego graphics accelerator) put the cursor in the monochrome layer, and NeWS supported it as an overlay plane, an optimization of xor drawing and undrawing. The enable layer would switch between the color and monochrome layers on a per-pixel basis.
With NeWS, I could open up the enable and monochrome layers directly and draw into them with PostScript to perform temporary non-destructive highlighting, and make monochrome overlay windows that didn't damage the color windows underneath. But it was a bit of a hack (much uglier than this cursor lag fix). Here is a window subclass that lifts a monochrome window into the overlay plane so it doesn't damage color windows behind it:
% Overlay plane compatibility hack for cg4 frame buffer.
% This is a nebulous layer abstracted from a messy program, to make it run
% on generic NeWS servers. It should be rethought and rewritten. Repent!
%
% Requires the devices /dev/cgfour0, /dev/cgfour0_ovl, and /dev/cgfour0_ove
% (which can all be major 39 minor 0, or whatever), and the following patch
% to the NeWS 1.1 server sources (but X11/NeWS doesn't need to be patched!),
% in order to take advantage of a cg4 under NeWS 1.1 (Otherwise it falls back
% to using exclusive-or).
[...]
% Damn damn damn! X11/NeWS Version 1.0 FCS on a cg4 can open up the
% enable plane, but there's a bug that trashes the enable plane color map,
% so we can draw in gray scales but we can't draw in white (black?).
The "Pseudo Scientific Visualizer" used it by making a PSVisualizerWindow subclass of OverlayWindow:
And the popup pointing hand shaped callout window also used it so it didn't have to repaint the color window underneath when you moved or dismissed it:
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).
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
}
}
}
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).
Already in 1963, the language CPL introduced "unless ... do ...", besides the "if ... do ..." inherited from ALGOL 60. Perl has just followed the example of CPL and BCPL, decades later.
Using "if" or "unless", whichever is more appropriate, is far more readable than "guard".
Moreover, there are many languages where an assignment or an initialization can appear in any place where an expression can appear. Such general rules are always better than special rules like allowing new bindings in a "guard", but not in an "if". Pattern matching does not need any special syntax, it should work in the standard alternative program structure of that programming language, regardless whether it is called "select", "case" or "switch".
It always annoys me when the creators of new programming languages demonstrate amateurism, by inventing new worse alternatives than those that existed in various older programming language, already many decades ago.
There are plenty of new programming languages that claim to be better than C, which may be true, but they fail to match programming languages much older than C.
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.
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?
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.
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.
The display controller and render device are completely distinct logical devices, even though they are often grouped in a "GPU". On mobile architectures they are quite far separated, leading to annoying problems surrounding what we on Linux call "split drm devices".
Updating plane properties such as to move the cursor plane around or disable it would by itself not block on render activities, as they are completely distinct blocks.
The render hardware could be powered down, but I doubt powering it up and compositing the cursor would take long enough to complete to cause any noticable lag.
Under the Linux APIs, updates to the display controller are done through KMS atomic commits, and one mistake you could do display-server side would be to provide a fence in this atomic commit that the scheduler will use to wait on long-running GPU work before using the provided graphics buffers. Under this API, none of the changes - including mouse movements - would then be applied until that fence is signalled. Changing plane associations can lead to resource reallocations that can be a bit heavy.
Not sure if the kernel driver in macOS works anything remotely similar to this, and the driver could also just be dumb and block on unrelated things ("let's just wait another vblank to see this apply....", "as we only need one plane now let's power down hardware and wait for that to settle..."). It could also just be windowserver that waits for work to finish on its own, not providing any cursor updates in the meantime.
The reality is that it will take reverse engineering or looking at actual code to know what's going on.
Since this is but an iPhone crammed into a laptop, could this behaviour stem from the fact that iPhones generally need not render a cursor?
No, the cursor just uses an overlay plane, and mobile architectures usually have far more planes (sometimes even an arbitrarily configurable amount), and more flexible hardware compositioning overall than desktop GPUs for efficiency reasons.
EDIT: Also note that there is nothing new with the Neo here, as all Macs since the M1 have used the same chip architecture as the iPhone.
Desktop GPU designs did not focus on tiny efficiency gains, and often only has a primary plane, a single overlay plane (for e.g., a video), and a dedicated cursor plane. Some even have to share a single overlay plane between all connected displays. It's a recent thing for desktop GPUs to get more flexible in this area, in part to improve laptop battery life in the cases where the laptop is almost entirely idle.
(For those unaware, a "plane" here is the entity in the display controller you configure to show a rendered graphics buffer, in a particular location and with particular transforms. You commonly have one plane that just covers the whole screen, and then sometimes put dynamic content on top in other planes so you can avoid having to redraw the main buffer when smaller bits of it change, like a video player or cursor. You could also e.g., scroll by rendering an entire document in advance and then move the plane around to reveal parts of it.)
> 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
Do modern machines still have custom hardware for cursors? That would surprise me, as a GPU can easily blit a small cursor on top of whatever gets drawn.
The cursor plane is the way to "easily blit a small cursor on top of whatever gets drawn". If the cursor was drawn on the primary plane, the primary plane would need to be redrawn (expensive!) or repaired (messy!) to change the cursor position.
This was a really informative and interesting reply articulated in simple enough terms that I am now interested in GPUs, thanks
But wouldn't the software cursor operations also go in the queue? I don't see the problem.
Modern GPUs usually have multiple command queues, at least one for application use (often separate queues for rendering and compute) and one for OS use. There's a good chance that this wasn't implemented on a chip intended for a phone.
For something as small as a cursor they could be doing direct framebuffer writes.
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.
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
AFAIK, they work just like in a non-composited desktop.
The problem with rendering the cursor into the primary plane is that, often, only the cursor changes, and you'd have to re-render the whole plane that contains the cursor. That is easily doable for modern hardware, but bad for power consumption and may also be higher latency. (The latency aspect gets interesting when dragging something on the primary plane - I think most compositors temporarily disable the hardware cursor in order to keep cursor and dragged object in sync.)
>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).
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.
Reminds me of a fix I wrote a decade ago. My Laptop would sometimes start emitting a high frequency whine when on battery. I figured out it only happened when the CPU went into performance states lower than P2 for power saving.
So I wrote a bash script that auto-started on battery mode and then calculated a hash every few seconds. Boom, whine solved. Terrible fix, but I never measured how much battery it cost me, so it was... fine.
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.
linux was plagued for a long time by lagging mouse cursor
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?
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.
not necessarily ubiquitous, but you can encounter some issues with "lagging cursor" even today, if you use standard raspbian for example
> usbhid.mousepoll=0 > to /boot/cmdline.txt > This option was implemented to enforce a mouse polling rate of 62.5Hz which dramatically reduced the XWindow event system update rate in certain circumstances (oddball or "performance" mice can have update rates of 1000Hz, which is silly).
There was a time when it was quite bad, especially if using Wayland and under heavy CPU or I/O loads. I think this has mostly been solved now, but I do recall getting frustrated with the switch to Wayland because of it.
Crazy this would be the case when the MacOS cursor has been buttery smooth and only ever lags if the entire system is about to go down even on 800Mhz G4 Titanium Powerbook this was the behavior.
A fix so amusing and ridiculous it gets the bug enough attention that Apple fixes it for real.
This is a great example of how to make a minimal app bundle with Swift. Thank you!
All an App needs on MacOS seems to be a binary and a little .plist
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
You could just put it in your calendar. 'Check if that hacky bugfix at ~/.dirtyhack.sh is still required with chmod -x ~/.dirtyhack.sh'
Or do a counter with read n<.hackycounter;echo $[n+1]>.hackycounter
When the counter hits e.g. 200, spam the user with notifications.
Bonus points if you manage to record the Facebook tracking pixel.
Steve turning in his grave
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.
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.
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."
Alan Dye would disagree.
https://daringfireball.net/2025/12/bad_dye_job
SGIs and Suns had overlay planes just for that. In fact SGI 4Sight would draw the popup menus in the overlay plane, too, since reading back the color framebuffer to draw cursors or perform xor highlighting or restoring the background after popping down menus was extremely expensive with that hardware.
Sun's framebuffers with 8 bit color + 1 bit monochrome + 1 bit enable (like the cgfour / GX aka Lego graphics accelerator) put the cursor in the monochrome layer, and NeWS supported it as an overlay plane, an optimization of xor drawing and undrawing. The enable layer would switch between the color and monochrome layers on a per-pixel basis.
With NeWS, I could open up the enable and monochrome layers directly and draw into them with PostScript to perform temporary non-destructive highlighting, and make monochrome overlay windows that didn't damage the color windows underneath. But it was a bit of a hack (much uglier than this cursor lag fix). Here is a window subclass that lifts a monochrome window into the overlay plane so it doesn't damage color windows behind it:
https://donhopkins.com/home/archive/psiber/cyber/overlay.ps
[...] The "Pseudo Scientific Visualizer" used it by making a PSVisualizerWindow subclass of OverlayWindow:https://donhopkins.com/home/archive/psiber/cyber/mics.ps
And the popup pointing hand shaped callout window also used it so it didn't have to repaint the color window underneath when you moved or dismissed it:
https://donhopkins.com/home/archive/psiber/cyber/pointer.ps
Sometimes the cure is worse than the disease.
Does anyone know if this is fixed in macOS 27?
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).
No
What's with "guard !foo else return" instead of "if foo return", is that just how Swift is written?
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:
can be written as: 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:
This is useful enough that Rust copied it in the form of 'let ... else {}' statements (but did not bring over boolean guard statements).Already in 1963, the language CPL introduced "unless ... do ...", besides the "if ... do ..." inherited from ALGOL 60. Perl has just followed the example of CPL and BCPL, decades later.
Using "if" or "unless", whichever is more appropriate, is far more readable than "guard".
Moreover, there are many languages where an assignment or an initialization can appear in any place where an expression can appear. Such general rules are always better than special rules like allowing new bindings in a "guard", but not in an "if". Pattern matching does not need any special syntax, it should work in the standard alternative program structure of that programming language, regardless whether it is called "select", "case" or "switch".
It always annoys me when the creators of new programming languages demonstrate amateurism, by inventing new worse alternatives than those that existed in various older programming language, already many decades ago.
There are plenty of new programming languages that claim to be better than C, which may be true, but they fail to match programming languages much older than C.
Perl has the negated if statement:
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.
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?
Embedded Swift in a script. That seems like a useful concept for small scripts on macOS. I will definitely steal this idea.
i hope they can fix it asap
The duality of TheTon’s and anotherpaul’s comments.
ah yes, the famous mac "Just works" OS
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.
host file nuke?
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