Fdupes-gui v0.2.1

In 2021, I mashed together this quick utility, a very simple gui front-end to fdupes because I needed to clean up a bunch of documents. It was also an experiment in trying out Flutter Desktop.

Last year I released it to the public on github, more as an educational tool for people wanting to see some flutter desktop app source. Because these days, I’m force to work on macOS, I also released a mac version of an app for the first time in my life. 😳

Turns out, there is 1 other person in the world, who used my app. He noticed the app wouldn’t find the fdupes exec if it was launched from the gui. It was a known shortcoming, but this bug report triggered me to make a better effort. 😉

In v0.2.1, when the exec is not found, you can locate it manually. The location is stored so that subsequent launches automatically use fdupes from the specified location.

Available for linux and macOS, windows might follow.

new app: fdupes-gui

A few years ago, I wanted to clear out the duplicates I had in my Google Drive. It’s not a trivial task as deleting files with the same filename does not cut it: I receive tons of generated pdf’s with the same filename and when time is short (or when being lazy 😉), I just save it to Google Drive as is. The inevitable consequence is: one day cleanup is needed. 😁

Anyone familiar with linux might think of the ‘fdupes‘ utility: it not simply compares the filename but, according to the manual:

comparing file sizes and MD5 signatures, followed by a byte-by-byte comparison

Excellent. Except, when you have to go through tons of documents and files, it’s not that practical. So, with my 2021 new year’s resolutions still fresh in my head, I persevered and coded a quick gui mashup.

Workflow

  • The gui presents a list of all file duplicate groups.
  • When you click on a group, you are presented with a list of all duplicates.
  • You inspect what the document is about by clicking on the filename, which opens it with the default viewer for this file type.
  • You rename one of duplicates to the desired final filename by clicking the ‘Edit’ icon.
  • You delete the renaming files using the ‘Trash’ icon.
  • The UI prevents you from deleting the last one 😉

Simple, but effective!

Release

I coded this a few years ago, but apparently never got to publishing the code, or even just a blog post. This weekend, I cleaned up the project and added the macOS platform (originally only linux was supported). I feel weird about supporting macOS, but the world is how it is: if you want to publish your app for iOS, you need to buy Apple hardware..

Find the project on github.

Quick KDE KWin hack: Ignore global shortcuts except alt-tab

From time to time a pet peeve can reach a critical level of annoyance at which it starts to irritate. You google it, hoping to find a solution or at least some allies, but if none turns up and you’re out of time, you simply give up and hope a solution will magically manifest itself one other day. But what if that day never comes? Luckily for us, open source enthousiasts, we can do something about it ourselves 🙂

Context

I’m quite an avid shortcut user. Linux/KDE is an environment where this type of user feels right at home. Not only do most actions in a software have a shortcut, you can also define lots of system-wide or global shortcuts. Kwin, KDE’s window manager defines quite a few out of the box.

Problem

This is all fine and dandy until you want to use this cross-platform software which you got used to in a different environment (i.e. windows at work) and you want to start using it at home. When the application is not (KDE) shortcut friendly or you are so used to the windows keymap that it’s a pain to learn a new scheme, you start to feel frustrated. Learning a new shortcut scheme seems the best solution but this doesn’t work well when you have to maintain 2 shortcut schemes in your head, depending on your environment (home vs work, your computer at work versus a colleague’s computer).

A typical example here would be some IDE, for example Intellij IDEA. Although the IDE does provide a KDE keymap by now, I started using it ages ago when there simply was no alternative keymap (nor a community edition or even official linux version, I guess). Also, I used linux only occasionally back then. These shortcuts are hard-wired by now and it is already hard enough to keep in mind whether I’m using Intellij or Visual Studio.

Another possibility is that the application really needs that much shortcuts that it just can’t bother with the shortcuts which may or may not be defined by the environment or workspace. One example of such complex application is Blender. Try it out and you’ll see what I mean. 😉

KDE, being the configurable desktop environment, does offer some configuration settings. For each window, Kwin allows you to define rules which match certain windows / applications which creates a config. Using this config, you can configure special window attributes. One setting is to block all global shortcuts.

This allows you to use your favorite application with its favorite native shortcuts. Of course, most people use more than 1 application at the same time. However, since all global shortcuts are blocked, the alt+tab shortcut to switch windows is blocked too. Alt+tab is not a special shortcut to KDE, it simply is a shortcut that happens to be assigned globally to the “Walk through windows” action exposed by the KWin component to the System Settings. Lacking any window switching shortcut, you adapt and start using the mouse to switch applications. There are times you cope just fine. But there are other times it is just one thing too much that annoys you. 🙂

Solution

So how to fix this? Just like any other problem you have with an open source application: fetch the source, fix and build! 😉

Since I just wanted a quick fix (I thought, let’s check this out for 30 mins, which turned out to be a lot longer of course), I chose to patch the behavior of the “Ignore global shortcuts” setting to exclude the Alt+Tab shortcut (more precisely, the shortcut currently assigned to the “Walk through windows” action). I briefly investigated KWin’s scripting abilities but it turns out the required functionality is not exposed.

I will now document the process, which took place on opensuse leap 42.3. You may want to tune out now if you don’t care about the gritty tech details. 😉

Where is the source?

I thought it had to be kwin, right? So I checked out the source from github and started searching for “Ignore global shortcuts”. It turned out to just call something in kglobalaccel which is not part of kwin.

Getting my hands dirty, I first fired up a VM I had lying around in order not to f*ck up my currently running system. Next I installed Qt Creator to easily navigate the code. Also, never forget you have to checkout the tag for the version you are currently running! (can be a treasure hunt by itself)

Browsing the source, I finally find a possible tweaking point in the src/runtime/component.cpp -> deactivateShortcuts method. It disables all shortcuts when a window is entered which has a “Ignore global shortcuts” rule. So I simply added an exclusion for the “switch windows” action.

Building a patched rpm

Time to try it out! In order to build it, you will need to install its dependencies. On an rpm based system, the easiest way to go forward is to do a “sourceinstall” of the rpm in case. For that, we first have to know which rpm contains the affected shared object (.so file).

You can take different routes to pin point the rpm. I checked the CMakeLists.txt to see what the output targets were. When you build, you can also see the class pass by and check into which library it gets linked into. Using that .so file, you can find the rpm using “rpm -qf <.so>”

An alternative way would be to find a kde related rpm matching “global” and then checking its contents (using “rpm -q –filesbypkg <rpm>”) for the .so file.

Once you know the rpm, you can easily install all required build dependencies by issueing a zypper sourceinstall command: “zypper si <rpm>”

The hard part: logging

I wanted to add some debug output to see if I was looking at the right place in the source base and how frequently the code got called. Now things got messy. You’d think patching the code was the hard part, guess what.. 😉

I had played with logging before in KDE, but of course things have changed with KDE 5. Nowadays, KDE uses Qt’s default logging mechanism. It meant figuring out the logging category used by kglobalaccel and finding a way to activate it. The logging category was nicely tucked away in logging_p.h: “kglobalaccel-runtime”. Activating it seemed to be trickier. According to the Qt documentation, you can alter the log level through an env var QT_LOGGING_RULES. Since I was adapting a core component, I needed to set the env var before logging in. On opensuse you can create a file /etc/profile.local which gets sourced by /etc/profile.

I added the env var and it seemed to work (=showed up), unfortunately still no logging. More precisely, nothing showed up in ~/.xsession-errors-:0. I started adding log statements all over the place, analysing the .so file to check whether my modified method was actually included in it (readelf -Ws libKF5GlobalAccelPrivate.so.5.32.0  | grep deactivate), etc.. Until I realised I didn’t check the journal (journalctl -b -0) yet, there it was. 🙂 Bonus points: the code change had its intended effect!

End result

So there I had it, a working patch WITH logging ⇒ pure SATISFACTION 🙂

Feel free to share this satisfaction by downloading the .so and installing it in /usr/lib64 (use at own risk). I’ve been using it for 2 months now without problems. It’s a good hack until a more fundamental solution is in place. First steps have been taken! 😉

Activating HW acceleration for embedded YouTube videos

Ever since Google Chrome became terribly slow in gmail, drive, etc regardless of computer or platform, I’ve picked up Mozilla Firefox again. The switch didn’t go painless but I really was tired of typing a whole sentence before Chrome would display it. This problem produces itself not only on google sites but actually in about any text box I would type, be it intermittently.

The main issue with switching to Firefox was stuttering video playback. As you may know, chrome bundles its own flash plugin which is actually the same plugin but tweaked to work optimally with chrome (pepper api). At the same time google controls distribution/patching.  So, if google can tweak the plugin for good performance, why can’t we? 😉

First thing I discovered, is that somehow flash hardware acceleration was disabled. You can enable this by right-clicking on any flash video and click on “settings”. In the “Display” tab, you can check “Enable Hardware Acceleration”.

flash enable HW acceleration settingSmooth youtube vids FTW! Fullscreen video’s also showed up on the correct monitor now (dual head setup). My joy was only for limited time, as I discovered hardware acceleration dit not work for embedded youtube video’s. I was happy nevertheless as the bulk of video’s I watch are on youtube.

However, today, watching the Jolla Tablet intro movie embedded on the site, I could not help feeling the itch again. Why oh why did this play fluently in chrome but did it suck so hard in firefox? Check out this framerate:

yt_embedded_noHWaccel1I started by creating a virgin system account to avoid having my 7 year old home dir, possibly dragging along some evil deprecated setting, be the culprit. This didn’t change anything but at least I had both a blank Firefox and Chrome profile to test with.

First I was under the impression that there would have to be a global flash settings file since when right-clicking on the embedded video, it showed the “Settings” as disabled. There does indeed exist such file: /etc/adobe/mms.cfg in which you can put “EnableLinuxHWVideoDecode=1”. This only crashed my firefox. I did install an additional vdpau package but it didn’t matter. Also, looking at the “Nerd stats” (right-click on video), I learned even youtube vids didn’t have hardware accelerated decoding, only accelerated rendering. So I didn’t proceed on this path.

Now let’s check out how chrome is doing it. Pulling up the “Nerd stats” did surprise me: chrome does not use flash by default for embedded video’s, it uses WebM/VP9!

This begs the question: how is Firefox’s WebM support? Turns out it’s no problem, just change your youtube html5 setting from “default player” (=flash) to “html5”.

youtube html5 settingsSo the  chrome pepper flash tweak actually came down on not using flash. 🙂 Youtube does this by default on chrome but not on firefox. Naughty Google!

You may notice that Firefox does not support all youtube hmtl5 features yet. In particular, you will be served VP8 video’s instead of VP9 which may make a difference in the available resolutions. However, Media Source Extensions and WebM VP9 can already be activated by setting:

media.mediasource.enabled = true

in about:config. Experimental h264 support can be activated with:

media.mediasource.ignore_codecs = true

You can track the MSE support in firefox in this bug report.

Itch scratched and fixed. Finally 🙂

Firefox ctrl+backspace behavior on linux

I’ve always hated why ctrl+backspace wouldn’t do what I expected in the address bar of Mozilla Firefox. So I stopped using Firefox. However, one day I tried it by accident on a windows box and was astonished it did work as expected! I didn’t care that much anymore since my main browser became Google Chrome. However, Chrome became more and more of a resource hog and even their owns sites like gmail and google drive run slower than on firefox. I started using Firefox again and got annoyed again over this small nuisance.

So I started googling the issue and found out that, apparently, linux users want non standard behavior because they are used to different selection behavior than for example a windows user.

I agree that double clicking a path in a console should select the entire path but I don’t see why that should affect the ctrl+backspace behavior. If I press ctrl+backspace in KWrite, it deletes the last word. If I press ctrl+backspace in the address bar in Dolphin, it will delete the last part in the path. The list goes on.. but I will never expect ctrl+backspace to be equal to “select all and press delete” which it does by default on Firefox/Linux.

Luckily, it turns out there’s an option layout.word_select.stop_at_punctuation to configure this behavior 🙂 You might also be interested in layout.word_select.eat_space_to_next_word.

DD-wrt: control radio on a Cisco Linksys E2000

Some people prefer to have their wifi turned off at night. DD-wrt already provides out of the box reprogrammability of the WPS button so you can use that button to turn the wifi off/on.

If you want to use a cron job to automate this process, you need to know the command line. I tried using the wl command:

wl radio off

Unfortunately this doesn’t do much. We might need to specify the network interface on which to apply the command. List the network interfaces using the ip addr command:

root@DD-WRT:~# ip a
1: lo: <LOOPBACK,MULTICAST,UP,10000> mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast
    link/ether c0:c1:c0:ab:6c:70 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast
    link/ether c0:c1:c0:ab:6c:72 brd ff:ff:ff:ff:ff:ff
4: teql0:  mtu 1500 qdisc noop
    link/void
5: tunl0:  mtu 1480 qdisc noop
    link/ipip 0.0.0.0 brd 0.0.0.0
6: gre0:  mtu 1476 qdisc noop
    link/gre 0.0.0.0 brd 0.0.0.0
7: vlan1@eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc noqueue
    link/ether c0:c1:c0:ab:6c:70 brd ff:ff:ff:ff:ff:ff
8: vlan2@eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc noqueue
    link/ether c0:c1:c0:ab:6c:71 brd ff:ff:ff:ff:ff:ff
    inet 178.117.xxx.xxx/20 brd 178.117.xxx.255 scope global vlan2
9: br0: <BROADCAST,MULTICAST,PROMISC,UP,10000> mtu 1500 qdisc noqueue
    link/ether c0:c1:c0:ab:6c:70 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global br0
    inet 169.254.255.1/16 brd 169.254.255.255 scope global br0:0
10: etherip0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop
    link/ether f6:1f:60:c5:50:bf brd ff:ff:ff:ff:ff:ff

I’m no network expert so I checked the MAC address of the wifi interface in the web admin Status > Wireless page ( http://192.168.1.1/Status_Wireless.asp ) and figured eth1 must be the wifi interface.
And indeed, using the following command it worked!

wl -i eth1 radio off

You can check whether radio state changes in the wireless status page mentioned above. For automation, put these commands in a cron job on the Administration > Management page ( http://192.168.1.1/Management.asp ).

VLC on opensuse 12.3

Last week, I installed opensuse 12.3 and encountered the following problem with VLC:

main decoder error: no suitable decoder module for fourcc `mpgv’. VLC probably does not support this sound or video format.

I had this for about any video format (mpgv for a DVD in this case). Turned out it is a package problem. Simply install vlc-codecs and you should be good to go.

Update: apparently, this is not a bug, but a feature, see
google+ post
mailing list post

Using KDE systray notifications from bash scripts

I just improved my Extract audio script to show a system notification when it’s finished. In the meantime I also have a “convert to mp3” script which proves useful if you don’t care about the original audio stream and/or you target a platform with limited decoding abilities:

ffmpeg -i %u -acodec libmp3lame -ar 44100 -ab 160k %u.mp3

To popup a KDE4 system tray notification at the end of the encoding process, simply add the following:

kdialog --passivepopup 'Finished converting %u' 3

The last value simply specifies the timeout in seconds. To chain the commands together, use a semicolon, so it also executes when the encode fails.

Using your EID on opensuse 12.1

In Belgium you can use your EID to login onto the federal portal for using electronic services, for example, for filing tax return. Installation instructions are provided for Windows, Mac and (Ubuntu) Linux. This is what I had to do to get it working on opensuse 12.1 on a Dell Precision M4600.

Installation

smartcard reader

Since the M4600 is a fairly new model, I had to upgrade my pcsc/ccid package to the latest version. It seems the M4600 comes with a Broadcom Corp 5880 smartcard reader which is connected through USB (internally).

Add the chipcard repo:

sudo zypper ar -r http://download.opensuse.org/repositories/security:/chipcard/openSUSE_12.1/security:chipcard.repo

and “switch system packages” in Yast. You should have installed at least the following packages: pcsc-lite, libpcsclite1 and libpth20.

Depending on your smartcard reader, you need a different pcsc plugin package. The Broadcom 5880 smartcard reader is supported through the ccid driver. This means we have to install the pcsc-ccid package from the chipcard repo.

eid middleware

Add the following repo by Pascal Bleser:

sudo zypper ar -r http://download.opensuse.org/repositories/home:/pbleser:/belgium-eid/openSUSE_12.1/home:pbleser:belgium-eid.repo

and install the eid-mw package. I also noticed the eid-mw-firefox package in this repo, but it did not seem to work in my case, possibly because I’m using 64-bit firefox.

configuring firefox

  • Install the belgium eid firefox add-on.
  • Trust Belgium Certificate Authority: Edit menu -> Preferences -> Advanced -> Encryption -> View Certificates -> Authorities -> Belgium root CA2 -> Edit trust -> check all checkboxes
I’m not sure whether the firefox add-on is really needed. Afterwards I uninstalled it and it kept working.

Troubleshooting

smartcard reader

  • check in /var/log/messages which device you have
  • most devices are connected through usb protocol. Check your usb device list:
    lsusb -v
  • google the device or check the device compatibility lists of the pcsc-<driver> packages. You can find the ccid device list here.
  • if you have a pccard interface for your reader, check whether the device is installed with:
    pccardctl ls
  • install the pcsc-tools and perl-pcsc package to have access to some smartcard reader analysis tools. Running the pcsc_scan tool should yield similar output like this:
  • If you get a segfault when loading the pcsc-ccid driver, for example:
    pcscd[3228]: segfault at 0 ip 00007f98bec38121 sp 00007fff2e806208 error 4 in libc-2.14.1.so[7f98bebb8000+187000]
    check whether you updated your portable thread library with the one in the chipcard repo (package name is libpth20)
  • be sure to be using all the packages from the chipcard repo by using the “switch system packages”.
  • firmware upgrade as suggested here, was not necessary. Read the whole thread to find out why a ccid upgrade was actually necessary.

eid middleware

The government created an application eid-viewer which you can use to read some public data from your EID. It’s a java-based app so you need a java JRE to run it:

java -jar eid-viewer-4.0.4-146_tcm227-178503.jar

You can obtain it from this page under the catory “other”.

firefox

Although I installed this add-on, I don’t believe it is needed. I did have trouble the first time I signed in: it succeeded, but redirected me to a page where I would again need to choose whether I wanted to sign on with EID or password. I closed firefox, and tried again, this time it just worked. You can surf to this test page to test whether everything is configured correctly.