Snippet Pixie 1.5.0

I've just realised that I forgot to post that Snippet Pixie 1.5.0 was released, almost 4 months ago!

Here's what the 1.5.0 released included:

  • Added search of Snippets in main window.
  • Added last used Snippets shown first in Search and Paste window.
  • Added shortcuts for main window actions such as Add Snippet (Ctrl+n).
  • Added support for system Light and Dark appearance preference.
  • Improved theming of window controls to be more consistent with system.

Being able to search snippets in the main window is very useful while adding or editing snippets, especially once you've accumulated quite a few.

Over time I've found that I tend to use the same handful of snippets over and over again while working in a particular context. So this release now orders the entries shown in the Search & Paste window by most recently used first, whether there's a search or not. This has proven to be a huge productivity boost for me.

Once you've got a good library of snippets created, adding shortcuts to the main window in this release doesn't really make much difference to you as you rarely using that window. However, when you're starting out with Snippet Pixie or in a phase of editing a bunch of existing snippets, this new feature will be very helpful.

The last two entries in the release notes relate to how the main and search & paste windows are themed. If a Linux desktop supports light and dark themes, Snippet Pixie should now switch its styling according to the user's preference. Along with that came a reduction in custom styling for Snippet Pixie, it's now using standard colours for the header bar and pretty much everywhere else so that it can easily switch between light and dark, and generally fit in with whatever desktop is in use.

Snippet Pixie 1.5.0 is available from the elementary OS AppCenter, the Snap Store, and nixpkgs.

2021 Goals

At the end of my 2020 Year in Review post I mentioned that I intend to write up some goals for 2021 so that we can all have a good laugh at how badly I fail to achieve them in a 2021 Year in Review post. So here we are, let's do this!

To me, goals are worthless unless they're S.M.A.R.T. There's a few variants of what SMART stands for, but the version I learnt many moons ago is as follows:

  • Specific - targeting a specific area for improvement
  • Measurable - progress can be measured numerically
  • Achievable - has to be attainable
  • Realistic - has to be achievable within the alotted time span
  • Time-boxed - there must be a target end date for reaching the goal

So, given the above, I'm setting goals for 2021 that cover areas of my life where I feel I need to make significant improvements, or keep on top of and simply not screw up.

Business

My business is software development, that's what I do, and love doing it. However, the vast majority of my income comes from being a contract software developer where I effectively trade time for money.

For a very long time now I've wanted to at least partially supplement my consultancy income with passive income from software products. While I've had some success with this in the past, at present I'm failing bad, with only WP Table Pixie and Snippet Pixie available as a way of generating passive income. The annual revenue from them combined might just stretch to a nice meal out for the wife and I (finger's crossed we can do that this year).

I don't think either of the above products have much chance of making any significant revenue in the long term, but my Secret Project might make something worthwhile eventually.

Goal 1: Release 1 new software product by 01/11/2021

My little secret project should be available for anyone to sign up for and use by 1st November 2021.

It's important to get the software to Minimum Viable Product and available for use by people I don't know. If it's not available for anyone to use, I can't possibly make any money from it.

Goal 2: Secret Project earns $10 MRR by 31/12/2021

My little secret project should have however many paying customers it needs to be earning $10 USD per month by 31st December 2021.

Just having that validation is key here, I can worry about growing revenue in the future. I need to do whatever it takes to get people interested in, trying and paying for it. There's a lot to that beyond simply making the product available for sign up.

The product may not even be something you pay for on a monthly basis, but there'll be some way of working out a monthly recurring revenue figure.

Personal Growth

While I've learnt a lot in relation to programming in 2020 having picked up Go, Svelte, and some ancillary technologies, I've really not grown my social skills as I had hoped.

On the face of things you'd think growing my social skills is a bit of a hard goal to quantify, but I think I have two goals that will achieve what I want in terms of helping me communicate better and improve my interactions with the World at large.

Goal 3: Write 12 blog posts by 31/12/2021

There should be a new blog post published on this site every month, for a total of 12 posts by the end of the year. While the goal is to have 12 new posts by the end of the year, I really mean to publish something every month.

I need to greatly improve my writing skills, and just writing something that is publicly available at least once per month should help with that.

I'm not even worried about how big each post is, or how profound it may be, I just need to write something on this blog.

I'm already over achieving on this goal as this post and 2020 Year in Review are definitely going to count! ๐Ÿ˜†๏ธ

Goal 4: Release 6 episodes of Always Developing by 31/12/2021

It doesn't matter whether I decide to release audio or video, but by the end of the year there must be 6 new episodes of Always Developing available.

Health & Fitness

I've been really lazy in 2020, and my strength and suppleness have suffered as a consequence. I've noticed this simply when going for longer walks with my daughter, or doing various DIY tasks around the house this year. Getting more fit and healthy will not only directly improve my quality of life, but is also very important for those that I love.

Goal 5: Practice strength yoga 156 times by 31/12/2021

That's 3 times per week of doing either Yoga Strength Basics for Beginners or Beginner Yoga Strength Classes.

These classes should help me achieve both increased strength and suppleness over time. I'm intending to start my day off by following these classes before sitting down for breakfast, catching up on the internet, and starting my work day. The classes have built in rest days, but my intent is to limit the sessions to work days, and leave weekends for other activities.

Summary

While five goals is quite a bit to juggle at one time, there's two sets of two that go hand in hand, and I feel all three areas balance each other and hopefully help one another too.

In January 2022 I'll write a 2021 Year in Review post and include a section reviewing how I got on with these goals.

I might even do an interim post at some point in the year to see how things are going and whether any course corrections have been required. That'll at least help with goal 3 anyway!

2020 Year in Review

I don't normally do year in review posts, but I feel like 2020 warrants one. Probably to satisfy a longing for closure, and to mark the beginning of what I hope will be a much more positive year.

That's not to say that 2020 has been a terrible year for me and my family, or for my business. In a lot of respects it's been a relatively positive year compared to some people's, but still, there's been ups and downs.

Business

I'm very fortunate to have been working with Delicious Brains as a senior software developer for over 6 years now. As a fully 100% remote company, the COVID-19 pandemic didn't disrupt the daily work routine too much as we're all already working from home.

I continued to work on WP Offload Media this year, a WordPress plugin that I'm very passionate about and keen to keep on moving forward.

At the beginning of the year I was the primary developer on WP Offload Media, in a team with Matt, who primarily worked on WP Offload SES. We bounced ideas off of each other and reviewed each other's code etc, but for the most part just got on with our work.

This worked ok, but WP Offload Media has become a bit of a victim of its own success, as the support load has increased significantly over time as more and more WordPress site owners rather than site developers have started using the plugin, and they tend to have less experience with cloud storage, content delivery networks, DNS, and general WordPress admin. Matt and I found ourselves doing quite a lot of support, and much less development on our respective plugins.

We weren't the only ones at Delicious Brains to be struggling with support detracting from development, WP Migrate DB Pro and SpinupWP also had the same problem as they saw increased popularity too.

Luckily Brad (owner of Delicious Brains) recognised the problem and has been effectively on full time recruitment duty for as long as I can remember now!

Since early on in the year we've had dedicated 1st line support staff trialled and come on board to help with the more administrative and technical sales style support requests for all our products. They've seriously improved the life for us software developers, and for Caillie who was helping us out as much as she could, detracting from her primary role too.

We've also had developers come on board this year to help speed up the development of all our products at Delicious Brains, along with a little shake up of the teams.

For me this meant losing Matt as he's now working with Pete on WP Migrate DB Pro, but getting a brand new team member on WP Offload Media, Erik.

Erik has gotten off to a flying start, we threw him in at the deep end and he's taken to it like a shark.

With there being no chance of a company retreat in 2020, and a general feeling of increased isolation, we've also started doing per team 10 minute stand-up video calls early in the day. For me this has been a massive improvement. Getting just a bit of face time with Erik each day helps immensely, not just for sorting out development related stuff, but for getting to know my Swedish team mate.

Another change at Delicious Brains was Iain switching to being a product manager rather than developer. While this happened relatively recently, this too has been a welcome change as Iain has already taken on some of the general product management tasks that detract from development time, but also brings in a different slant on things that I struggle to see myself.

Erik, Iain and I are working on some big things for WP Offload Media, and I'm particularly looking forward to 2021 as I've got some interesting and fun development lined up.

Side Projects

For the most part my side projects have suffered from a lack of attention this year. While I've managed to throw myself into my work at Delicious Brains, all the goings-on in the World have been quite distracting and left me less inclined to work on stuff in my spare time.

Snippet Pixie

The most active of my side projects this year was Snippet Pixie, the little text snippet expander application for Linux that has been used quite a lot while writing this post! ๐Ÿ˜‰๏ธ

At various times throughout the year I've got the madness for improving Snippet Pixie and worked many hours to release almost complete rewrites or bug fix releases. Apparently seven in total.

Developing a snippet manager for Linux has turned out to be quite a tall order, it's harder than it might at first seem. However, once I switched full time to Linux in the summer, it became incredibly important that I had a reliable desktop text expander, and version 1.4.0 was born. This release of Snippet Pixie threw away the notion of universal automatic expansion and conceded that hot-key expansion was a much more reliable mechanism for the many non-native applications that are used on Linux these days.

I'm very proud of Snippet Pixie, and use it many times every day. I think in 2021 I need to work on making it better known in the Linux community, listen out for what people want from it, but otherwise just keep it true to its core reason for being and keep it ticking along.

There are some potential ways I could make a little income from Snippet Pixie in the future by offering some adjacent services that also help push it forward, but I'm not sure it's quite ready for that yet.

WordPress Plugins

I have two WordPress plugins that I maintain on the side, WP Table Pixie and WP Cron Pixie. Neither are particularly popular, or have received much attention from me this year.

WP Cron Pixie is completely free, and was originally born from a blog series I did for Delicious Brains. It just ticks along and does its thing. I use it quite a bit, have kept it up to date as the underlying technology changes, but otherwise it just exists. I have a vague notion of revamping it by rewriting the front end with Svelte, and back end with WP-REST, but that's maybe best left until I get the green light to add a part 4 to the blog series for it (which is unlikely as there's many more things we can blog about).

WP Table Pixie is freemium, there's a read-only plugin on wp.org, and you can upgrade to the premium version to add editing of postmeta, options and other metadata records. Apart from keeping it compatible with WP I've not worked on WP Table Pixie this year, mainly because it seems to be a very niche product, makes very little money, and I'm not sure it will ever have much of an audience. It's a little frustrating as it's a plugin I use virtually every day when helping WP Offload Media customers, it's great for checking what's really going on in a WordPress site's Media Library data. I seriously considered just making WP Table Pixie completely free this past year, but lack of time, a few more sales than I expected, and that little voice in the back of my head saying I should maybe give it another go kept me from doing it. I'm not sure what's in store for WP Table Pixie in 2021, it may be a make or break year.

Podcasting

In August 2018 I started the RustyElm podcast, a microcast journal of my attempt to learn the Rust and Elm programming languages.

In March 2020 I finally admitted defeat and started a new podcast called Always Developing.

And then there were tumble weeds.

I've not podcasted again since that "reboot".

It's weird because I've been continuously developing software and enjoying it ever since that first Always Developing podcast episode. The problem is I've just not felt that my rambling on about what I've been up to is particularly interesting.

I seriously considered doing some (not so) live streaming of me working on Snippet Pixie or my Secret Project, even have an OBS setup for it, but just not the confidence to actually do it.

I'm a pretty private person, and so social media and tooting my own trumpet in public does not come easy. While my colleagues at Delicious Brains hear my views on subjects more readily than they probably wish, I'm not one for spouting my opinions to people that I don't know. Yes, I'm your typical nerdy introvert, until comfortable enough.

Podcasting was going to be a means for me to combat these tendencies, to improve my social skills, get a few things off my chest and journal, kinda. So far it hasn't worked out, but maybe I'll find a format for podcasting or similar in 2021 that'll help me come out of my shell.

Secret Project

There's a little side project that I've worked on every now and then for at least 16 years now. It's been a tiny little bit of software that I use as a project to test new programming languages and technologies on. It's a great vehicle for learning, has had many incarnations in desktop, mobile and web forms with many languages, and has never ever got past prototype status, even though I've had spells of using it consistently to great success.

In 2020 I started playing with it again, this time using Go for the back end with CockroachDB as the database, and Svelte (Sapper) for the front end. I've thoroughly enjoyed working on it, including taking a bit of a detour into writing Juju Charms in Python for deployment.

For Go and Svelte I've done my usual deep dive into the technology, thoroughly absorbing them, reading through tutorials and getting to know them well before properly launching into developing with them. It's been a blast, they're both fantastic platforms that just make sense to me.

When I decided to write a custom Juju Charm for the project (which has now ballooned to 3 charms by the way), I took a very different tact to picking up Python in order to work with the Operator framework. For this I tried what I call "Stackoverflow" mode, no deep diving, just trying to get somewhere by searching DuckDuckGo or Stackoverflow for answers and perusing existing code on GitHub.

I'm not sure I would ever recommend this style of learning, but it's been relatively effective for the task at hand given that the Juju Charms I've been working on aren't the primary focus of development. As I write this it's been the part of the project I've worked on the most recently, partly because it's been just such fun. Juju is a wonderful system, and Python is a very easy language to accomplish tasks with.

This little side project has had enough iterations now that I think I should probably just make a commitment to it and take it seriously this coming year. It's nothing Earth shattering, but it may be helpful to some people, enough that they're willing to pay a few quid for it. So I think 2021 might be the year that it finally gets properly worked on and released.

Personal

If you've got this far you may be under the impression that 2020 has been a bit of a quiet year for me in terms of business and side projects. Thankfully it's also been very quite in my personal and family life too.

Although the pandemic has seriously dampened our plans for celebrating some big family birthdays and anniversaries this year, my family and friends have all managed to stay safe and weather the storm.

There's been a lot of "in 2021 we'll ...", and hopefully that'll all come to pass, but really I just hope we all continue to stay safe and healthy throughout the year, and the World in general gets back on its feet.

The one thing I've not really taken care of this year is my fitness. Although I've kept a good healthy weight, somehow, I'm pretty sure I've lost a good bit of strength and suppleness through a lack of exercise this year. That is probably the one major thing I intend to address in 2021 to ensure I'm fitter and healthier for both myself and my family. But that kind of talk is probably better suited to a "goals" post.

2021 Goals

Seeing as I've broken the habit of not writing year in review posts, I guess I might as well also write a looking forward post too.

Stay tuned for a much much shorter 2021 Goals post, where I'll briefly go over what I hope to achieve in 2021, so that this time next year you and I can laugh at them in a review post. Assuming my goal of writing a 2021 year in review post should come to pass! ๐Ÿ˜†๏ธ

Snippet Pixie 1.4.0 Released

I give up, there's no way to get Snippet Pixie to auto-expand snippets while typing in non-accessible applications such as browsers or those developed with Electron etc.

I tried monitoring keystrokes at a higher level for tell-tale snippet triggers, then faking keystrokes to backtrack select characters and check the select clipboard for an abbreviation match. This turned out to be a rather resource intensive and flaky method of working out whether a snippet should then be stuffed into the clipboard and pasted over the selection.

I iterated on that method a lot, came up with some routines that made it more and more reliable and performant, but still, some times you had to wait for the checking to do its thing and could often see the selection walking when the error correction and retries kicked in to combat the temperamental async Linux clipboard. If you created any abbreviations that ended in commonly used letters or punctuation characters then you could often find yourself frustratedly waiting for Snippet Pixie to fail so you could carry on typing.

I created a snippet on purpose that I knew would piss me off, it ended in a "$". I did this to drive my desire to improve the algorithm whenever I was writing code for my day job in PhpStorm, you use $ a lot in PHP. It worked to some extent, it caused me enough headaches that I often ended up right clicking Snippet Pixie's icon and hitting "Stop Snippet Pixie" so I could get on with my day. This would impact other areas of my day as I would seriously miss not having a text expander while answering support requests etc. Just silly things, like not wanting to type "WP Offload Media" over and over again, "ome`" is way shorter and easier to type.

A little over a fortnight ago I was using the most excellent Ideogram app by Cassidy James Blaede to pop open an emoji picker and pick ๐Ÿ‘๏ธ for the millionth time that day, when it occurred to me that maybe I should just give in, stop fighting non-accessible apps, and also create a shortcut popup window to search for and paste snippets. So that's what I've done.

Snippet Pixie's Search and Paste Window

You can open Snippet Pixie's "Search and Paste" window at any time by hitting its shortcut, which by default is Ctrl+` (grave).

You can then just start typing the abbreviation or anything you remember from the abbreviation or its contents to narrow down the list of snippets. Hit tab to focus the list, and then either navigate the list with the usual up and down arrows etc and hit Enter on the one you want to use, or hit its number. You can just press Escape or the Ctrl+` shortcut again if you change your mind and don't want to paste a snippet.

When you do choose a snippet from the Search and Paste window it'll close and the expanded text will be sent to the system clipboard and then pasted into whatever app you had open before hitting the shortcut.

It works really well, and the window and general usage pattern may look really familiar to some people. That's because a lot of the code for the Search and Paste window and how it safely closes and pastes is adapted/liberated/borrowed/stolen from Clipped by David Hewitt.

Until I started this little exercise a couple of weeks ago I'd never actually used Clipped before, but had used some of its code when trying to get Snippet Pixie compatible with browsers etc previously. I was led to that code via comments in Ideogram's own code that first time, it worked well for what I needed those bits to do. When I started thinking about how to do a popup snippet search and paste window I first took a look at Ideogram, but that quickly led me to Clipped again. This time I took a much deeper look at the app's code, and had a play with it, it's fantastic! As much as I love the convenience of snippets, I'd not really used a clipboard manager before, but now that I've got Clipped I'm a convert, it's saved me having to go back and re-copy and paste stuff many times.

Anyway, back to Snippet Pixie. It wasn't all plain sailing, but I was able to adapt a good chunk of code from Clipped for the new search and paste window, sprinkle in some code for working with snippets, showing their abbreviations and bodies, and a few little tweaks here and there, and Bob's your uncle, we have a search and paste window opening from a shortcut. ๐ŸŽ‰๏ธ

While I've now been able to rip out all the janky clipboard code I was using for searching entered text for an abbreviation to auto-expand, auto-expansion is still in place for accessible apps. So if you're a fan of Quilter, LibreOffice, or any other native Linux app that is accessible, then you're all good, type your abbreviation and Snippet Pixie will expand it in-place for you. You don't have to use the shortcut.

However, if you decide that you prefer the shortcut, or maybe still have issues with auto-expansion in accessible apps ๐Ÿ˜ฑ๏ธ, then Snippet Pixie now has a new "Auto expand snippets" setting you can toggle on and off in its revamped preferences menu, which has also gained a "Shortcut" submenu.

Snippet Pixie's New Preferences Menu

Oh, yeah, the shortcut, that too was initially inspired by some of Ideogram's code, but I also found some interesting stuff in Clipped regarding being able to change the shortcut. In Snippet Pixie's Shortcut preferences submenu you can change the shortcut from Ctrl+` to whatever suits you best. Just click on the existing shortcut and you'll be asked to type a new one.

Snippet Pixie's New Shortcut Preferences Menu

In the above screenshot you can also see a couple of settings related to how the shortcut works.

You can turn on "Search selected text" if you like. When on, if you have any text selected in an app before you hit the Snippet Pixie search and paste shortcut, then that will be used as the initial search for snippets. It's off by default for a reason though. While at first I thought it was an awesome idea, in reality I often found that the search text was being populated with text I didn't expect, such as previously copied text. This is an unfortunate side effect of how the Linux clipboard works, it's quite easy for the "select" (a.k.a Primary) clipboard to end up with the contents of the copy clipboard. That kind of makes sense when you think about how you first select text and then copy it, but it is a bit annoying some times.

However, if you also use the on by default "Focus search box" setting, then it's not a huge deal as you can just start typing to replace what was automatically inserted into the search box. This is a diversion from how Clipped works, which naturally selects the list of previous clipboard entries as you're very likely to want something just recently clipped and therefore it's more convenient. But with Snippet Pixie I find I'm generally searching for an abbreviation anyway, so by default I've switched initial focus to the search box. However, turn off that "Focus search box" setting and the first entry in the list of snippets will be selected when the window opens. This does have its attractions too when "Search selected text" is enabled as you could find you've got a narrow list of snippets to hand and can quickly select the one you want without having to hit the tab key to focus the list first. ๐Ÿคทโ€โ™‚๏ธ๏ธ

So that's it really, Snippet Pixie 1.4.0 is now available on the elementary OS AppCenter, and will be available on the Snap Store soon¹.

Here's the changelog for Snippet Pixie 1.4.0:

  • Added Search and Paste window, opened with shortcut Ctrl+` by default.
  • Added "Auto expand snippets" checkbox to preferences menu for enabling/disabling snippet expansion while typing in accessible apps.
  • Added ability to change Search and Paste shortcut in preferences menu.
  • Added preference for whether text selected before using shortcut is used for initial search.
  • Added option to focus search box when using the search and paste shortcut.
  • Fixed support for Wayland.
  • Removed auto expanding of snippets in non-accessible applications such as browsers and electron apps (use shortcut for search and paste window instead).

Enjoy!


¹ I'm holding off on the Snap just now as there's a couple of improvements in 1.4.1 that are important to Snaps, once through review and test I'll promote it to the Snap's stable channel.

#000: Why Always Developing Exists

Always Developing
#000: Why Always Developing Exists
/

Ian rambles on about why this podcast exists, and why the RustyElm podcast has come to a close.

There's a new version of WP Cron Pixie! ๐ŸŽ‰

WP Cron Pixie 1.4.1 changelog:

  • Fixed wrong data refreshing into non-primary subsite of directory multisite
  • Minor updates to framework and build tools.
  • Tested with WP 5.4

Enjoyed attending #dttech last night, my first @DigitalTaunton event.

Liked the format of 2 main talks + 3 lightning talks after a break.

Great talks, and very well organised event, a lot of work must have gone into it, congrats to all! ๐Ÿ‘

Snippet Pixie 1.3.1 Released

This week I released Snippet Pixie 1.3, with zero new features, but it took many many hours of development.

Umm, what? How could you bump Snippet Pixie up a version, and claim to have spent "many many hours" on development, but not have any new features?

And isn't this post titled "Snippet Pixie 1.3.1 Released"?

Well, take a look at the gif attached to this post, that's a snippet expanding in Standard Notes, an Electron based application. ๐Ÿ˜ฑ๐ŸŽ‰

Demo of Snippet Pixie working with Standard Notes (Electron)

Ok, to some people that might not mean anything, but believe me, it's a major relief to have Snippet Pixie able to work with Electron based apps, and of course, Chrome and Chromium too.

Before v1.3, Snippet Pixie relied on apps using the ATK library, or at the very least, doing what's needed to work with the accessibility DBus interfaces that AT-SPI interacts with. Further still, the user had to be typing in an EditableText and Text interface compliant control. There are many Linux applications that are ATK/AT-SPI compliant, but unfortunately a few very popular ones are not.

The biggest trouble maker for Snippet Pixie was Chrome, turns out it's quite a popular browser. ๐Ÿ˜‰

And many companies build cross platform apps with Electron, a technology that basically uses Chrome under the hood, so they weren't working well with Snippet Pixie.

I tried all kinds of things to try and get Chrome and Electron apps to play nice, and there was the odd occasion when a control here and there would actually work with the accessibility framework, but in the end I had to throw out the accessibility stuff and go "old skool".

Well, I say "throw out the accessibility stuff", but that's not quite true, and is the reason for v1.3.1, but we'll come to that in a minute.

Snippet Pixie still uses AT-SPI for monitoring keystrokes, but it's using a method that is a little more greedy in its scope, monitoring "all windows" for the current app rather than just the currently focused text control. With this method, Snippet Pixie can see when a key is pressed that matches the last character of some snippet's abbreviation, and then go look to see whether previously entered text matches an abbreviation.

This may sound less performant than monitoring the currently focused text control, and technically it likely is, but, it turns out that with this method I was able to eliminate a huge performance problem that earlier versions of Snippet Pixie suffered.

Snippet Pixie used to have to notice when the current app changed, then go look through all the widgets in that app to try and find the currently focused one, which hopefully was an editable text control. When that app happens to be a spreadsheet with thousands of widgets, that search for the currently focused control (cell) could take a noticeable amount of time. Now, we're not talking minutes here, not even seconds, but if it took even anything near half a second, you'd notice it.

Because Snippet Pixie is now monitoring at a higher level by default, it does not need to go look for a widget to attach monitoring code to. That's a big boost in performance, it no longer feels like Snippet Pixie is slowing down app switching for some apps.

Hang on a minute, if you no longer know where the text is being entered, how are you checking whether an abbreviation precedes that key stroke that matches the end of one or more abbreviations?

Blimey, you do ask some very intelligent questions don't you? ๐Ÿ˜‰

So this is where a huge amount of time was spent in developing this release. When I first thought of building Snippet Pixie, one of the initial ideas I had for how to get the just entered text was to see if there was a way to walk back through the text with some sort of selection method, and then check the contents of the selection. I didn't get too far in that investigation before finding the accessibility interfaces, which seemed like a much saner approach.

Recently I found out about another open source text expander style app called Espanso. There was an issue raised on the project about the clipboard being overwritten when an expansion happened, or something like that, can't quite remember. But anyway, seeing that made me think that maybe I should take another look at my mad idea of selecting text, stuffing it into the clipboard and then checking the contents of the clipboard.

After much research and experimentation, I eventually managed to get Snippet Pixie to start a text selection by "pressing" the shift key and then "pressing and releasing" the left cursor key, then fake a copy shortcut, check the contents of the clipboard, and then keep hitting the left cursor key until an abbreviation was found, or the max length of known abbreviations was exceeded.

This kind of worked, and once I had an abbreviation match it was a cinch to then stuff the expanded text into the clipboard and fake a paste hotkey. Thanks for the initial code Clipped!

Grabbing the selected text into the clipboard wasn't ideal though. It was very flakey, using the copy shortcut for every extra character was hit and miss, and there was some weirdness with the clipboard not always updating.

I learnt a lot about the async mechanisms that the Linux desktop (GTK+ based in this case) clipboard uses, and that there's such a thing as a clipboard that most people think about, but also a second selection clipboard that auto populates when text is selected.

With that knowledge to hand, and after much experimentation with threads and strategic yielding and microscopic usleeps (I hate handling threads, but who doesn't?), I finally got a nice mechanism that recognises the abbreviation via selection, and then expands via the clipboard.

Over time I fine tuned the mechanism, and added a bunch of speed ups and error correcting retries to the way abbreviations are searched for, and ensured that the current clipboard is saved away and restored before and after the expansion respectively. The attached gif is intentionally slow so you can see the walk back working, even error correcting, but in general the mechanism is way quicker.

It worked really well with Chrome, Chromium and even Electron apps, but when I tested LibreOffice Writer, which had worked fine with the previous version of Snippet Pixie, it did the most weird things and lost text selection all the time, making abbreviation recognition impossible.

So I brought back the core abbreviation recognition engine of the old accessibility framework dependent mechanism, and sure enough, that still worked with LibreOffice Writer. Well, it wasn't quite that simple, I also had to add back a mechanism for being notified of when an accessible control was focused, and do a bunch of work to dynamically swap between the "all windows" monitoring method and the control based one as appropriate when apps are switched.

I did not need to re-add the old widget lookup code though, and I was able to improve the accessibility based mechanism with the abbreviation lookup speedups and threading from the new text selection mechanism.

In the end I got to a place where the previously supported applications still worked with the faster accessibility based text editing, and added support for a much wider set of applications via the new text selection mechanism.

When I applied those speed ups to the old mechanism that I created while developing the new one, I did miss one problem that necessitated v1.3.1. I used a slightly different monitoring mode with the re-implemented accessibility based code, async rather than blocking, kinda needed as part of the performance improvements and thread usage. Sometimes the control where the text was being entered would report the caret position incorrectly, especially near the beginning of the control, and after initial switch into the app. Turns out I needed to yield the abbreviation checking thread for a split second to let the app get itself together.

There are unfortunately a few apps that remain incompatible with Snippet Pixie 1.3.1.

The one that hurts the most for me is Firefox, my preferred web browser, which at some point in its last few releases started to misbehave when Snippet Pixie was in use. The old accessible method that Snippet Pixie used stopped working for some reason, something must have changed in Firefox to stop keystroke monitoring. I wouldn't be surprised if this was an intentional security measure, but I bet it also stops screen readers from working now.

When forcing use of the new text selection mechanism with Firefox, it keeps losing focus while you're typing, which breaks everything, text stops being entered. To get around this problem temporarily, until I can find a proper solution, or Firefox gets fixed, Snippet Pixie now blacklists Firefox so at least Firefox is usable, even if snippets don't expand.

Similarly, Snippet Pixie has never worked with terminal emulators, their text handling mechanism is fundamentally different. To avoid any potential issues with the new text selection mechanism that Snippet Pixie uses, a bunch of popular terminal emulators are now blacklisted by Snippet Pixie and it turns off abbreviation checking while they're the active application.

This new blacklisting mechanism actually brought to the fore another performance improvement for Snippet Pixie, as turning off the abbreviation checking speeds things up in incompatible apps. And along with this change, Snippet Pixie also monitors less keystrokes in general now too anyway, as if you're using either the Ctrl or left Alt key, as far as I can tell you can't be entering a character. The right Alt Gr key is still monitored in combination with normal keys though as that's how you generally enter extended characters such as โ‚ฌ and ยข.

The final incompatibility with Snippet Pixie 1.3.1 is Wayland compositors. This too hurts as I'm a fan of Sway, but alas the way I've had to implement active window / app checking is via libwnck, which unfortunately only supports X11.

I'm actively trying to find either an alternative robust method of tracking the current application that works in X11 and Wayland, or an additional Wayland only method that I can use when Wayland is detected.

So I guess you could maybe class the expanded compatibility and vastly improved performance as new features, but even if you don't, I'm sure you can see why I bumped the version from 1.2.x to 1.3.x.

Anyway, that was a bit of a rambling retrospective into what went into Snippet Pixie 1.3.1. Hope you enjoy this release, please submit bugs and feature requests in the GitHub repo.

Get

Get