I was today years old when I learned of the BroadcastChannel Web API, which facilitates intercommunication between windows, tabs, frames and iframes on the same domain (thanks to Cory House on Twitter).
At a glance, the API is surprisingly simple, so I figured why not give it a spin.
After consulting the ever-valuable MDN Web Docs on the topic, I had a BroadcastChannel spun up in a matter of seconds – here’s the overview and demonstration of it in action.
To setup my playground, I simply opened up a new Chrome window – and then 2 tabs, which I pointed to my blog here. At this point, all that’s left to be done is to new up an instance of BroadcastChannel in both tabs, setup an onmessage event listener in the receiver tab, and then to broadcast a message from the sender tab.
Cool, cool, cool. So pretty simple – here’s the explicit flow of this experiment in case it’s not clear from the screenshot captions:
Open 2 tabs on the same domain – ‘https://blog.immatt.com’ in my example
In tab 1, create a new BroadcastChannel instance via “new BroadcastChannel(‘channel-name’);”
In tab 2, also create a new BroadcastChannel instance for the same channel name – e.g. “new BroadcastChannel(‘channel-name’);”
In tab 2, setup an event listener for the ‘onmessage’ event exposed on our BroadcastChannel instance
Back in tab 1, broadcast a message to all subscribers of our channel by using the ‘postMessage()’ function exposed on the ‘sender’ instance of BroadcastChannel
Check back in tab 2 to see our super awesome message!
Here’s the expanded console object of the recieved message for a better look at the MessageEvent payload:
Also worth mentioning, browser compatibility is pretty solid – with it having landed in most major browsers around 2015/2016 (except Edge, which was 2020).
Anywhos. There you have it… Inter-tab/window/frame/iframe communications via the BroadcastChannel Web API!
As a follow up to my last post, I’ve decided to dig in a little more to some of the upcoming TC39 proposals. The proposal that we’re reviewing today provides a few new ways to work with Arrays in an immutable way – a proposal titled “Change Array by copy”.
As the title “Change Array by copy” suggests, the new methods covered by the proposal provide Array functions which allow working with arrays in an immutable fashion (with the assumed intent of reducing side effects often associated with mutable objects, which are capable of being directly changed).
Included under the proposal are:
You can check out the collaborative view of this proposal on GitHub.
Let’s dive in!
Similarly to Array.prototype.sort(), Array.prototype.toSorted() exposes a helper function capable of sorting members of an array sequentially. Unlike to Array.protptype.sort(), Array.prototype.toSorted() returns a new array, by copy, leaving the original array untouched. To see this in action, see the following example:
Up next, we have Array.prototype.toReversed() – essentially, the immutable form of Array.prototype.reverse(). Just as reverse() reverses the member order of the array, so to does toReversed() – but, again, without modifying the source array being operated on/against.
Last in our one-to-one function comparison is Array.prototype.toSpliced() – similar to the long standing and familiar Array.prototype.splice(), which is used to remove or replace elements within an array. As we can see in the following example, we’re capable of removing and replacing array elements with both splice() and toSpliced() – with the distinction that toSpliced() doesn’t modify the original array, and instead provides us a new, updated one via copy.
And finally, we have Array.prototype.with(). Unlike the previously discussed parts of the proposal, with() doesn’t really have a similarly named existing function – though we’re all likely familiar with the logic in play. When working with an array, it’s often common practice to reassign a value within an array by assigning a new value using the target’s zero-based index – with() exposes exactly this functionality, via a function call. See the following example to see Array.prototype.with() in play:
Brought Array.prototype.group into my Nodejs module project via core-js (“import group from ‘core-js’;”)
Still want to read more? Great!
As if often the case with developers, you complete school and you quickly realize that you need a job. Armed with a bunch of CS theory, and what’s basically a beginners level of experience, you pick up new skills and tricks as you need them along the way – but rarely is there sufficient time to learn much else outside of this while maintaining balance in other parts of your life…
This is the process for years for many/most developers – you show up for work, you’re given a feature to implement, you encounter something you don’t know how to do, you do a little research, you try a few things until you find something that works, and then you move on – rarely thinking about it again. As the years go on, you keep doing that thing that you found that worked – but rarely do most of us dig in deeper to understand more or to find alternatives. Again, there’s unfortunately only so many hours in a day, week, month, year, and lifetime – and there’s a lot to living outside of punching a keyboard.
But I digress… I’m trying to be better – I’m trying to be proactive… I’m trying to dig deeper, to gain a greater understanding and to perhaps learn some alternative approaches to old problems along the way.
We have an array of JSON objects named ‘inventory’ – with standardized properties associated with each contained object. As we can see, calling array.group() passing in ‘type’ as our associative element – conceptually, we can think of this as a category. As such, we can see the resulting output of our group() call is an object comprised of our ‘type categories’, which are arrays containing the matching type objects.
I thought this was pretty cool and useful, so I wanted to try it out… Naively, I thought “Nodejs always has bleeding edge stuff – so let’s just plop in our playground code…”.
jsonArr.group((country => country));
TypeError: jsonArr.group is not a function
at Object.<anonymous> (D:\w\nodejs\csv.js:45:9)
at Module._compile (node:internal/modules/cjs/loader:1159:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
at Module.load (node:internal/modules/cjs/loader:1037:32)
at Module._load (node:internal/modules/cjs/loader:878:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
This is all new to me, so I figured I should just start throwing stuff at the wall to see what sticks… Up first, let’s just install…
npm install --save core-js
Now let’s figure out how to use this bad boy… Since I have my Nodejs project setup as a module, I figure I will just try to import group. Note: I’m not saying this is the best way to go about this, or anything of the sort – just sharing my process of discovery in case there’s interest.
import group from 'core-js';
So far, so good.
Now, consider my project… It’s a basic utility script – imports a CSV, and then coerces the CSV data into JSON array containing objects that represent said data…
I feel that it’s worth mentioning another interesting and useful resource I ran across while playing this morning… The unofficial ES Proposals site, which is a labor of love from Apple Software Engineer Saad Quadri. Check it out!
One of the first things one might notice is that the tutorial targets Angular 14 – but since I’m really wanting to get a jump on Angular 15, I figured I’d forge ahead and try to tackle whatever issues may arise as they arise.
Since the tutorial largely just works in Angular 15, I’m not going to reproduce it step-by-step here – instead, I’m just going to highlight some of the issues I encountered when following along verbatim.
So, yeah… The tutorial mostly just translates to Angular 15, and most experienced Angular developers will be able to quickly workaround any issues that may arise from working through this Angular 14 tutorial in Angular 15… But if you’re curious about my journey, please feel free to continue on…
Hiccup #1 – in the ‘Create a new application’ section of the tutorial, we’re shown how to strip down our application in order to remove the ngModule (basically a cornerstone of ‘standalone components’) – and as part of those instructions, we’re shown how to enable production mode by leveraging the long familiar ./environments/environment.ts file… Okay… But I’m getting an error indicating this long standing file isn’t present in my project… odd… that fella is always hanging out there…
feat(@schematics/angular): remove environment files in new applications
This commit removes the usage of environment files and `fileReplacements` in new application projects. Previously, the environment files was used to distinguish between a prod build to invoke `enableProdMode`. The `enableProdMode` however needed only for the case of JIT mode in production mode, which is a rare case as JIT mode is recommanded to be used in production.
In the CLI, calling `enableProdMode` is not needed as `ngDevMode` it's set using the minifier.
Whelp… That settles that… Moving on…
Since we no longer have this environment.ts file out of the box with new apps, it seems logical to assume we can skip some steps – basically, we just need to ensure we bootstrap our now-standalone AppComponent.
Skipping ahead to the next section, “Display the photos”, things seem straight forward enough… It’s worth noting that there seems to be a bit of a typo in the HTML, as the closing ‘article’ tag isn’t properly formed – no worries, as we just need to add an ‘>’ to make it valid.
Upon saving and running our updated project, we will see that while things are technically working, they aren’t working great because we’re missing some assets – namely, the images…
Continuing on to ‘Add a new standalone component’, everything in the original tutorial translates perfectly to Angular 15 and we can see our lazy loaded component as expected when we click the ‘Find out more about these guys!’ button as instructed:
Another small note to make… Once you get to the ‘Add event handling to the form‘ section, step 4 of the ‘Add the send message form model to the component’ subsection instructs us to remove the default constructor:
Whelp… We don’t have a constructor in our newly created Angular 15 standalone component… Not particularly important, as it was empty and not really doing anything – but why doesn’t it exist?! MY ADHD WILL NOT ALLOW ME TO CONTINUE ON WITH WHAT I SET OUT TO DO UNTIL I KNOW… After a bit more poking around the Angular CLI repo, I see the following indicating that ngOnInit and the default constructor have been removed in Angular 15, as apparently users of these features generally prefer to simply add them manually: https://github.com/angular/angular-cli/commit/301b5669a724261d53444d5172334966903078c0
The next section, ‘Add a chat dialog’, just works. Unrelated note: I really liked this section… Having never played with a virtual agent / chat system, I learned something new, which is always fun! And that’s pretty much it – standalone components in Angular 15…
At this point, I’m going to stick a fork in this write up and consider it done. The remainder of the Angular Standalone Component tutorial details deploying the project to Google App Engine with Express.js – which I feel is a bit out of scope for this write up, which was to detail the hang ups I encountered working through this Angular 14 tutorial in Angular 15 (which were very minimal – YAY!).
With some of my newly found ‘free time’ while Funemployed, I really wanted to start playing around with some of the newer projects that I’ve simply not had the time or energy for.
I began my journey with Deno as I normally do – essentially iterating on some basic Hello World types of projects to get familiar with the dev flow, tooling and capabilities. Pretty quickly, I encountered something in my codebase that confused me – a warning notifying me that the deno window typings didn’t have everything supported by window exposed. Surprisingly, it wasn’t just me randomly plugging in code that landed me here – it was in following along with the Deno lifecycle docs that brought me to this error.
At this point in my journey, not only was I getting the warning in VSCode, but I was also unable to get beforeunload or onbeforeunload to fire… Hmm… So off to Google I go – which lead me to this thread discussing a related matter.
In digging a bit deeper, I came to realize that beforeunload/onbeforeunload weren’t firing due to my Deno version – with support for these not being added to window in Deno until v1.24.0 (and me currently running v1.23.0). “Alright”, I thought – “I just need to upgrade and this will all be solved.”
Sure enough, once on 1.24.0 I was able to play with beforeunload/onbeforeunload – but the “Element implicitly has an ‘any’ type because type ‘typeof globalThis’ has no index signature.deno-ts(7017)” warning remained…
Having wished I had more time to contribute to open source over the last several years, I saw this as an opportunity to make my wish a reality – and so I did what any developer would do, created a fork and started to work on a new branch in the hopes I could become a Deno contributor!
As most experienced devs know, stepping into a large and complex codebase isn’t always the easiest thing to do – especially if you’ve never worked with some of the core tooling. With this being my first real exposure to Rust, I was completely unfamiliar with Cargo and how to go about building and testing my changes in an efficient manner… Fortunately, after a handful of web searches, I learned the basics of working in Rust and with Cargo, how to run specific tests by name, and I was off to the races to become a real life Deno contributor.
My commit is simple enough – really just a few lines to add beforeunload and onbeforeunload to the type definition for Deno window, and some updated integration tests to ensure everything is working as expected – you can see the pull request / merge here. While a small contribution by pretty much all standards of measurement, it felt good to see an issue, fix the issue and contribute that fix back to the community – and I hope to be doing more of this in the near future.
So, what’s next? Well, I guess I can actually begin with what I set out to do – learn Deno (rather than Deno’s codebase) and start playing with Fresh! 😁
Just a quick post – if for not other reason than I’ve not made a post in a while. As you may know if you follow me on social media elsewhere, I was laid off from my job of ~12yrs middle of September – so, as of today, I’ve been FUNemployed 25 days (It’s okay. I was offered the option to relocate, but that unfortunately was not really possible as my wife and I are somewhat rooted where we are at). One random observation about being unemployed – non-work time passes by twice as quickly as work time.
Anywhos… One of my goals for my newly found free time was to move all of my personal sites to a new VPS instance since I’d been on the previous underpowered instance for about 6 years. I’m happy to say that I was able to get the new server set up, and all sites+content migrated with next to no downtime (aside from intentional reboots for OS/package updates). If you see something not quite right, please reach out and let me know – but in my testing and spot checking, nothing significant is standing out.
So, aside from a new server setup, what’s to come? I can’t really say. I plan on spending some of my free time picking up some new skills (Nunchaku?), so tune back in from time to time to see what I’m doing on that front if you’re interested.
I am currently seeking a new gig, though not particularly aggressively – so if you know of something that would be a good fit for an experienced full stack developer with a wealth of Angular experience, please don’t hesitate to reach out to me. In the meantime, I’m going to do a bit of learning, experimenting, playing and honey-dos 🙂
I recently found myself on yet another Angular + Bootstrap project. Usually, when spinning up a new Angular Bootstrap project, this means npm installing a library like @ng-bootstrap, but this time we wanted to keep things as vanilla as possible.
“How to use Bootstrap in an Angular application without jQuery?”
Since we’re in Angular, and since it’s generally considered a bad idea to use jQuery in an Angular project (though it is most certainly possible), we were forced to think about how to best use Bootstrap “from scratch”.
Up first – get a major pre-req out of the way… It’s been a while, so I guess I should ensure I’m on latest LTS😲
For this project, we’re also going with the latest and greatest from Angular, so…
Now lets get a clean Angular workspace spun up…
For simplicity, we will start slow – simply displaying a Modal from the AppComponent in the presentation of a Confirmation Dialog.
I’m opting to go with a Modal because it’s a frequently desired component of Bootstrap, and I believe that it allows us to demonstrate a number of angles with regards to using a Bootstrap Modal ‘natively’ from Angular (without jQuery).
Normally, I’d opt to go with self-hosting for my libraries, but since this crash course is more focused on how to use Bootstrap natively in an Angular application rather than productionizing the solution, I’m just going to use a CDN from the Bootstrap getting started docs to get things wired up.
To make things a bit easier on ourselves, we’re also going to install the Bootstrap types package from the Definitely Typed project as a developer dependency in our project.
npm install @types/bootstrap --save-dev
Now that we have the basics set up, let’s start in our AppComponent by importing Modal from bootstrap (via the @types/bootstrap package installed in the previous step):
To get our Modal setup, we’re going to utilize the AfterViewInit lifecycle hook to wire up our event listeners so that we can respond to our Modal instance:
As a sanity check, let’s go ahead and wire up the Modal as simply as we can – triggering the modal show with a button click:
As you can see in the above code, we’re able to simply create a Modal instance in TypeScript-land thanks to our @types/bootstrap library -then we can simply call ‘show()’ to open our new Modal:
Okay. That’s all well and good, but unless we’re just wanting to show some static message, this Modal is pretty lackluster.
Let’s go back to our AfterViewInit lifecycle and set some things up… But what exactly? Perhaps we should go take a quick, cursory glance at the Modal docs…
Alright… So we’ve got a handful of events we can respond to… For the purposes of this example, we’re going to focus in on ‘hide’ and ‘show’.
In addition to wiring up event listeners for ‘show’ and ‘hide’, we’re also going to change our implementation a little bit – rather than passing in the element from our template, we’re going to access the element via the @ViewChild property decorator. And lastly, we will log our events to the console:
Some points to note in the above code… We’ve introduced the Angular property decorator @ViewChild(…) – this has enabled us to stop passing in the element from the template via the template variable as we were originally doing. We’ve also added some code to our ngAfterViewInit lifecycle method, which is responsible for listening to the ‘show’ and ‘hide’ events – simply logging the ‘type’ property associated with the Event via the processDialogEvent() method.
Let’s check it out:
Whelp… Still pretty lackluster… One could be forgiven for mistakenly concluding we’re just showing the same demo as earlier – but we know they’d be wrong because this is a completely different monster altogether (since we’re using ViewChild and listening to/logging events now)!
Alright… Let’s get this thing done… Right now, we just have a message modal – but we need a confirmation dialog… So we will spruce things up a bit with some formatting/structure and we will add a couple of user prompts – something for them to confirm (or not).
And here’s how it looks in action:
Now it’s starting to look more like a proper confirmation dialog!
Something I’d like to point out at this point in the process. Remember our event listeners? Perhaps you noticed we added a new ‘X’ close button element, and that this element has an interesting ‘data-bs-dismiss’ now present. Bootstrap supports interaction via data attributes, and this attribute demonstrates how to close this modal instance using one such data attribute – read more here in the docs. Oh, yeah – and the event listeners? Still listening – even when we’re closing via the data attribute:
But we still need to do something about those button clicks… And as cool as being able to close the modal via the data attribute is, we don’t really know if the close was by clicking outside of the dialog or if it was intentional via the ‘X’ – and I’d think the ‘X’ could commonly be interpreted as “No”, as where closing via clicking outside of the dialog could be “I’m declining to answer right now”, and that perhaps we want to handle those two interactions differently.
First up, let’s add a new method to assess if the user likes to rock or not – ‘userRocks’:
Next, let’s wire this up on the template to the ‘X’ close button and the other choice buttons – passing ‘true’ when they do and ‘false’ when they don’t (I have a feeling those ‘false’ ones rarely get used, and only by people you probably wouldn’t enjoy writing apps for):
And let’s see it in action:
Cool-cool-cool. Looking more and more like a proper Confirm Dialog by the minute! But we have a bit of an issue… We know if the user rocks or not – but most users would expect the dialog to do something other than log to the console, which they wouldn’t even be aware of unless they’re a super 1337 hacker looking at the console while trying to find their exploit.
Let’s start simply by having the modal hide after the user has provided an answer… Easy enough – let’s just modify our userRocks method to call ‘hide()’ on our Modal instance:
Now we’re cooking! Let’s put this baby to bed! At this point in time, we have a functional confirmation dialog that allows the user to let us know if they like to rock or not – all that’s left is to do something based on the user’s willingness to rock.
For the sake of brevity (🤣🤣🤣 Never been a strong suit of mine), we’re just going to introduce a few lines of code to our userRocks method and some supporting code to our AppComponent implementation. Namely, we’re going to add another Modal (why not?! This is a Modal example, afterall!) as well as another ViewChild that makes accessing an element within the Modal a bit easier so that we can mess with it in our userRocks() method based on the user’s input.
Here’s our updated component TS:
And here’s our updated template:
And here’s how it looks running:
We like to rock:
We have sensitive ears and “refined” musical tastes:
There you have it – how to use Bootstrap 5 from Angular 14 ‘natively’.
While we really only covered the Modal here, many/most of the approach we’ve reviewed here translates to other Bootstrap Components.
I hope that you’ve found this helpful and perhaps even a little entertaining. If you would like to check out the full source for this project, feel free to check out the project here: https://github.com/mattezell/bootstrap-5-demo
Okay, okay… I’m sure Facebook, Instagram, WhatsApp, and Co won’t be going anywhere anytime soon – but today has been interesting.
Unless you live under a rock and/or actually followed through with your declaration to leave Facebook “for totes real this time”, you’re likely very aware of today’s outage of some very popular services.
With a mixture of cries, sighs, and giggles, the world has been collectively forced to come to terms with what a day in their life without Facebook/Instagram would look like.
To me, one of the highlights today has been the brand clowing taking place on Twitter (unquestionably the dominant social media platform today), which has included Facebook brands, such as Instagram and WhatsApp, playing along themselves.
I won’t go too deep into the technical, as there are people far more qualified than I who have already done so (here’s one from ArsTechnica). But basically, there are services that monitor and share routes that are used to make devices/services communicate with other devices/services on the Internet (RGP – Border Gateway Protocol) – and a configuration update was pushed(reportedly by Facebook themselves) that deleted the routes that told the rest of the Internet how to access the Facebook-owned stuff.
To add insult to injury, reportedly the Facebook staff tasked with cleaning up this mess have been locked out of the physical locations that they require access to as a result of this screwup 🤣 Making matters worse, both Facebook/Instagram users, coupled with client applications (such as the Facebook and Instagram apps installed on Phones that automatically poll for updates), are hammering all of the DNS services that play a role in getting users from point A to point B, bringing these vital services to their knees. We’re now hours into the outage, with no end in sight – it’s almost as if the Internet is a house of cards, just waiting to collapse (Narrator: “it is”).
tl;dr – The popping issue is likely caused by the audio device’s power-saving configuration – and so changing the configuration may eliminate the issue.
I wanted to do a ‘quick’ write up on the ‘audio popping issue’ that many Thinkpad owners have reported, as well as a solution/workaround. I recently purchased an X1 Extreme Gen 2 and quickly noticed the annoying popping issue once I got everything setup with my typical desktop arrangement – e.g. USB C dongle connected to HDMI, with external speakers connected to the LCD receiving the video/audio signal over HDMI.
As many others have reported on various forums around the Internet, the issue essentially manifests as an audible popping noise, which is generally observed just before a sound begins playing or within a few seconds after the sound stops playing. People who play music/video all day often don’t even notice it, as the audio device never actually toggles power states as it is constantly active. The most common way to reproduce the issue when troubleshooting is ensuring that no audio has played for a few seconds, and then playing a short audio file such as a WAV – at which time an audible ‘pop’ may be heard before the sound plays and shortly after the sound finishes.
It’s worth noting that I already somewhat knew where to look to work around this issue, as pretty much every laptop I’ve purchased in the last decade have had this popping issue in one way or the other – and the approach described in this post has by far been the most successful for me in addressing this issue on the various laptop models on which I’ve encountered it.
Overview of Issue
At the heart of this issue is power management settings coupled with hardware operational realities. Within the registry are various settings responsible for controlling the various devices within your computer (amongst other things) – some such settings are ones dealing with how devices are handled when not considered as being in use. For audio devices, this is generally 3 settings:
ConservationIdleTime – this setting controls how long to wait before the device is considered idle when the power management is in a conservation state.
IdlePowerState – What state should the device be moved to when either of the idle time windows has been met.
PerformanceIdleTime – this setting controls how long to wait before the device is considered idle when the power management is in a performance state.
So, essentially our registry is saying “depending on the current power management mode of the PC, change the power state of this device to something else after a period of time of inactivity has passed”.
Unfortunately, this powering down of an audio device isn’t as smooth as we’d often hope. Due to the powering down and powering up of the device, there’s often an audible pop associated with the power state change – and so we’re seeking to eliminate the power state change in order to eliminate the associated popping noise.
Most computers have multiple audio devices – and often all of those devices are affected by this popping issue, though not always. In this writeup, I’m going to focus on the audio device that I am actively using and having this issue with – and I may, at a later time go adjust the others if I identify a need to do so. In my specific situation, I’m using the NVidia High Definition Audio via HDMI – and so we will focus on that.
Modifying the Registry
WARNING: You can mess up your PC via the registry, so proceed with caution when using regedit.
When working with the registry, you’re likely to find a lot of key/value collections that appear to be the same if you go searching around – and this is because they are, as the registry actually uses pointers to find the active setting in play. Ultimately, we’re concerned with ‘CurrentControlSet’ as this is the collection pointing towards the actual settings.
Here is my registry path for the targeted audio device (NVIDIA High Definition Audio):
Note: I will provide all matching collections at the end of this document for reference.
Since I am currently experiencing the popping issue on the NVidia High Definition Audio interface, I’m going to focus on the PowerSettings in the CurrentControlSet for this specific device. To ensure that we’re modifying the correct part of the registry, we can check out our device in Device Manager and ensure that our Class Guid matches the GUID in our registry path (e.g. 4d36e96c-e325-11ce-bfc1-08002be10318):
What we’re seeking to accomplish here is to prevent Windows from putting this audio device into power saving mode – as ultimately it is the power saving mode that’s causing the audible pop when a sound isn’t actively being played.
As you may have inferred from the Device Power States document, a state of D0 is the ‘working state’ and D1, D2 and D3 states are various power-saving modes supported by the device.
When looking at our registry configuration, we see the following:
As one may have expected, we see the IdlePowerState for this device is 03, which corresponds with D3 – the most aggressive of the various power-saving states. D3 essentially cuts the device off – it’s this cutting off that results in the audible pop. With consideration of all of the applicable settings here, we’re seeing “when in conservation mode and in performance mode, consider 4 seconds the idle time – when 4 seconds has passed, set the device’s power-saving mode to D3”.
I’m going to go a bit of overkill here by setting the idle time to something that won’t be realistically hit in normal usage, as well as setting the idle mode to ‘working state’ (D0).
As you can see in the above screenshot, I’ve set the idle times to FF FF FF FF – which translates to 4294967295 decimal, and since this setting is for seconds it means we’ve made it so that 49,710 days must pass before this device is considered idle… As can also be seen from the screenshot, we’ve changed the Idle Power State from D3 to D0 – so even if the idle time is hit, the device should remain in the active D0 state.
After making our changes, we simply need to reboot the PC for them to go into effect. Note: We’re only making changes for Windows, so if you’re experiencing this issue under Linux then you will need to perform similar operations to change how the driver handles power management there.
After making the discussed changes, my pops have essentially gone away. Now I only notice a pop the first time the speakers become activated in my Windows session, as well as when shutting down.
I figure that it’s logical to assume that this may have an impact on battery life since we’ve essentially disabled power management for this audio device, though I am not certain how severe this impact is.
I also don’t know what other side effects this change may have on your system – so proceed with caution, with the understanding that I am not responsible for you borking your system 🙂 As mentioned, I’ve done this on multiple laptops over the years and they are all still functional.
Good luck! -Matt
All Registry Matches on my Thinkpad X1 Extreme Gen 2
If you’re a techie, you’ve probably heard of the shiny new Windows Terminal. While not currently available via an official Microsoft build, I decided to give it a spin – which, due to Microsoft’s commitment to Open Source over the last handful of years, is now possible!
Essentially, the new Windows Terminal is a wrapper application of sorts that allows for a tabbed CLI interface for all supported command line environments within Windows. Bash (via WSL)? Check! Powershell? Check! Old faithful CMD? Check, check and check!
Of course, unifying all CLIs isn’t sexy enough for Microsoft in 2019 – no sir! In addition to providing an all-in-one interface for the various CLIs now running under Windows, a slew of customization features have been added as well – with more currently in the pipeline for the coming releases.
This post isn’t intended to be an installation/build tutorial, but instead is more of a fluff piece detailing my personal experiences getting up and running, as well as a couple of tips and tricks picked up in my little bit of time spent tinkering.
I was able to get running relatively easily. I found the official readme instructions for the project pretty solid – getting me 99% of the way there. If you’ve not tried, I’d recommend visiting the Github link and checking out the Getting Started section: https://github.com/microsoft/terminal#getting-started
One of the first things you’re likely to notice is the requirement to be on Windows build 1903 ( >= 10.0.18362.0). Though by no means complicated, this was by far the longest part of the setup for me. Initially my efforts to manually download and install the build update proved fruitless, largely due to me having missed a required incremental update between what I was running when I started and 1903. Fortunately, a couple of quick Googles revealed that mere mortals, such as myself, could use the built in Windows Update to get to 1903 – once I got all of the required updates in place, I was eventually presented with the option to install 1903.
After getting Windows 10 up to 1903, I realized that I didn’t have Visual Studio proper on my newest dev machine – this proved to be the next longest part of the process. Having been using VSCode exclusively for the last year+ doing Angular dev (and in part due to no longer having a personal MSDN), I’d just not found a need for Visual Studio until now. Being a bit out of the loop on the IDE, I decided to go with the latest and greatest – installing 2019 Community.
There you have it – the bulk of the technical work. 1) upgrading Windows 2) installing Visual Studio. With these two time sinks out of the way, I was able to follow the rest of the instructions pretty much directly and get a working build (note: as mentioned in the readme, I was prompted to install some additional tooling as a result of opening in 2019, but this was seamless and handled automatically by VS).
The observant observer is probably thinking “Well… Okay… Lots of words to essentially say ‘I did it by reading the linked instructions’… Why am I reading your post?” Well, let me ask you a couple of questions, in turn, observant friend… Do you like running your app after building? Do you like animations in your CLI to breakup the mundane monotony of executing command after command? Well, then you’ve come to the right place! Keep going!
Running Windows Terminal
If you’re like me, you found yourself doing a victory lap after CTRL+Shift+B didn’t blow up your PC. If you’re like me, then you likely found yourself scratching your head about which one of the many build output artifacts you should be haphazardly clicking on in order to see your awesome new Windows Terminal. The answer: “None of them”. Something that wasn’t quite clear to me was that the application actually needs to be locally deployed in order to properly run. To deploy, simply right-click the ‘CascadiaPackage’ project and then click ‘Deploy’. Note: If you’re following the instructions, you’ve enabled Developer Mode, which is required – if you’re not following the instructions, then shame on you.
Once deployed, you should be able to locate “Windows Terminal (Dev Build)” in your Start menu.
Okay, great! We have a terminal!!! But… we already had a terminal (or few)… So what?
Multiple CLIs – One Windows Terminal
Towards the top right of your terminal window, you should see a ‘+’ and down arrow. Fortunately for me, Windows Terminal picked up all of my currently installed CLIs – PowerShell, CMD and Ubuntu Bash via WSL. If I want to open up another instance of the default CLI (PowerShell for me), I can simply click the ‘+’ and it will open a new tab with a new CLI instance! Additionally, key bindings are likely similar to what you’re used to in other apps – CTRL+T to open a new tab, and CTRL+W to close the current tab.
You can also click the down arrow in order to get a drop-down list of all of the configured CLIs – selecting one to open an instance of that CLI in a new tab!
But what if Windows Terminal didn’t pick up all of my CLIs? Or what if I add additional CLIs (say via different Linux subsystems)? Enter ‘Settings’. When you click settings, you’re likely to be prompted for which viewer/editor you would like the profile config file to be opened with – in my case, I just went with the suggestion default of VS Code. Once open, you will see a JSON file containing the default configuration for Windows Terminal similar to the following:
By scrolling down, you can find the individual CLI profiles – here are a couple of mine:
While I’m not 100% of the various configuration properties, I’ve learned enough to be dangerous – I’ve learned enough to set things on fire… But we will talk about burning the house down shortly – for now, back to the topic at hand. If your desired CLI isn’t automatically found, you can easily configure it by copying/pasting one of the existing configurations as a new ‘profiles’ entry, and then modifying the commandline and other relevant properties to suit your needs! Easy peasy!
Animate All The Things!!!
So back to setting things on fire… Odds are you found yourself going down this rabbit hole not out of your hate of having multiple windows open, but instead because you like shiny new things as much as I do. Odds are you probably saw a really cool demo showing fancy color schemes and backgrounds and thought “holyfugginshizbawls! I can haz animated CLIs too?!”. Well, as fate would have it, you can! While I again am not 100% on all of the configuration possibilities, I’ve fumbled around enough to figure out how to animate my various CLI instances – which I will share with you here.
To get started, we need a new property in our profile config – “backgroundImage”. This string value may point to a local image file, or (best I can tell) any network accessible image file that your little heart desires… But who really cares about regular old static images anyways? What is this? 1999? Fortunately, not only are static images supported but so are ANIMATED GIFS!!! By setting the value of this property to a path string to an animated gif, we are enabled to razzle-dazzle all inferior onlookers with our clearly superior terminal.
Behold and be amazed!
Another setting of interest is ‘backgroundImageOpacity’, which (hold on to your seats!) allows you to set the opacity of the CLI instance’s background. Here’s my PowerShell configuration rocking the synthwave:
Something that’s worth noting, and something I don’t yet fully understand – ‘useAcrylic’ in relation to using ‘backgroundImage’. In my experiences thus far, I must set useAcrylic to false in order to set a background image and have it actually load – when set to true, my CLI instance seems to fall back to simple color configurations (with Acrylic’s glassy transparency goodness, of course).
Here Be Dragons
So far, I am digging the new Windows Terminal. That said, it’s not been the most stable of experiences for me personally. As I’ve tinkered, I’ve found myself in a non-operational state multiple times with the Windows Terminal – at which time a full reboot has been my only discovered recourse. I’ve not quite nailed down what causes the ‘Abort’ crash – so far, it just seems to happen after the Windows Terminal has been up and running for some unknown period of time. Eventually, Windows Terminal will vanish, with an error dialog indicating a problem – with the process crashed, there’s no process to terminate, but subsequent attempts to relaunch will result in the same error message being displayed until reboot… more to come.
Anywhos. I hope that you’ve enjoyed reading about the Windows Terminal as much as I’ve enjoyed learning about it! Happy tinkering! -Matt