Meme about github and ms

I do not use social media, unless github, gitlab, or WordPress.com count. But, here is my hashtag for the week: #movingtogitlab.

With the disheartening news about a week ago of a malevolent force taking over the community darling github.com, I have decided to move my projects to gitlab. Plus, I was awakened to the fact that github’s value-added bits are closed source. Well, what an interesting situation! And I was just getting a few stars on some of my repositories too.

Check out the traffic of the gitlab github importer: https://monitor.gitlab.net/dashboard/db/github-importer?orgId=1.

I will be sharing over the next few posts some tools I used to facilitate this process. I had some help with the gist one, and I used a simple tool for the git repos.

Someday I may even run my own instance of gitlab.

xfe spec Fedora 26 with proper build dependencies

See the spec file at https://gist.github.com/bgstack15/ec1677daa1d19a9e1f5124068619e813.

The wonderful X File Explorer does not properly describe what is needed to compile it. So here is my research to help anyone else trying to compile it on Fedora 26.

dnf install rpm-build intltool fox-devel glib-devel libpng-devel libXft-devel freetype-devel gcc-c++

Compiling FreeFileSync on Fedora

FreeFileSync is a great open source GUI application. Think of it as the GUI for rsync.

The Freefilesync team does not provide an rpm of the software, but they do provide the source code. Now, the team does not allow direct linking, so that link has a HMTL5 rel=”noreferrer” which might make it work for you.


I finally got a scriptlet to work with download the source code! Use this:

wget --referer "https://www.freefilesync.org/download/FreeFileSync_9.4_Source.zip" --user-agent "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0" https://www.freefilesync.org/download/FreeFileSync_9.4_Source.zip

So, once you open up the zip file of the source code, you need to modify a few things. Please examine the patch I wrote:

diff -Naur FreeFileSync/Source/Makefile FreeFileSync.fc25/Source/Makefile
--- FreeFileSync/Source/Makefile	2017-10-05 09:54:58.000000000 -0400
+++ FreeFileSync.fc25/Source/Makefile	2017-10-22 21:33:01.445470939 -0400
@@ -10,8 +10,8 @@
 LINKFLAGS = -s `wx-config --libs std, aui --debug=no` -lboost_thread -lboost_chrono -lboost_system -lz -pthread
 #Gtk - support recycler/icon loading/no button border/grid scrolling
-CXXFLAGS  += `pkg-config --cflags gtk+-2.0`
-LINKFLAGS += `pkg-config --libs   gtk+-2.0`
+CXXFLAGS  += `pkg-config --cflags gtk+-3.0`
+LINKFLAGS += `pkg-config --libs   gtk+-3.0`
 #support for SELinux (optional)
 SELINUX_EXISTING=$(shell pkg-config --exists libselinux && echo YES)
diff -Naur FreeFileSync/Source/RealTimeSync/Makefile FreeFileSync.fc25/Source/RealTimeSync/Makefile
--- FreeFileSync/Source/RealTimeSync/Makefile	2017-10-05 09:54:58.000000000 -0400
+++ FreeFileSync.fc25/Source/RealTimeSync/Makefile	2017-10-22 21:33:19.853796285 -0400
@@ -7,8 +7,8 @@
 LINKFLAGS = -s `wx-config --libs std, aui --debug=no` -lboost_thread -lboost_chrono -lboost_system -lz -pthread
 #Gtk - support "no button border"
-CXXFLAGS  += `pkg-config --cflags gtk+-2.0`
-LINKFLAGS += `pkg-config --libs   gtk+-2.0`
+CXXFLAGS  += `pkg-config --cflags gtk+-3.0`
+LINKFLAGS += `pkg-config --libs   gtk+-3.0`
diff -Naur FreeFileSync/Source/ui/main_dlg.cpp source.fc25/FreeFileSync/Source/ui/main_dlg.cpp
--- FreeFileSync/Source/ui/main_dlg.cpp	2017-10-05 09:54:58.000000000 -0400
+++ FreeFileSync.fc25/Source/ui/main_dlg.cpp	2017-10-22 21:33:01.446470957 -0400
@@ -1024,7 +1024,7 @@
     globalSettings.gui.cfgFileHistory = history;
-    globalSettings.gui.cfgFileHistFirstItemPos = m_listBoxHistory->GetTopItem();
+    //globalSettings.gui.cfgFileHistFirstItemPos = m_listBoxHistory-gt;GetTopItem();
     for (const Zstring& cfgFilePath : activeConfigFiles_)
@@ -4862,6 +4862,7 @@
+    /*
     if (shouldRunPeriodicUpdateCheck(globalCfg_.gui.lastUpdateCheck))
         flashStatusInformation(_("Searching for program updates..."));
@@ -4869,6 +4870,7 @@
         periodicUpdateCheckEval(this, globalCfg_.gui.lastUpdateCheck, globalCfg_.gui.lastOnlineVersion,
+    */
@@ -4877,6 +4879,7 @@
     //execute just once per startup!
     Disconnect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnRegularUpdateCheck), nullptr, this);
+    /*
     if (shouldRunPeriodicUpdateCheck(globalCfg_.gui.lastUpdateCheck))
         flashStatusInformation(_("Searching for program updates..."));
@@ -4890,6 +4893,7 @@
                                     resultAsync.get()); //run on main thread:
+    */

You will need a set of packages installed to compile:

dnf install -y boost-devel compat-wxGTK3-gtk2-devel gcc-c++ gtk+-devel gtk3-devel wxGTK-devel wxGTK3-devel

Cinnamon adds “Show all workspaces” setting to Alt-tab appSwitcher

The story

I recently made a pull request to Cinnamon to add the “Show all workspaces” setting to the window list of the panel. To complement this feature, I decided to add the feature to the alt-tab utility.

My journey began with trying to find the alt-tab code in the Cinnamon project. It took me quite a while, but eventually I found it in appSwitcher.js. At first I started tinkering with lines 36-39

function matchWorkspace(win) {
    return win.get_workspace() == this && !win.is_skip_taskbar();

But this proved to not be the right spot. Later on I realized this was not the correct spot logically, but putting code here would work. It just wouldn’t make sense underneath the title “matchWorkspace.” You shouldn’t even get to the matchWorkspace function if you’re just showing all workspaces anyway.

So then I found this section of code

            // Switch between windows of same application from all workspaces
            let focused = global.display.focus_window ? global.display.focus_window : windows[0];
            windows = windows.filter( matchWmClass, focused.get_wm_class() );
            // Switch between windows of current workspace
            this._showAllWorkspaces = global.settings.get_boolean("alttab-switcher-show-all-workspaces");
            if (!this._showAllWorkspaces) {
                windows = windows.filter( matchWorkspace, global.screen.get_active_workspace() );

And that was what I wanted. The snippet above already includes my adjustment. Line 73 is the logic that reads the gsettings schema. And it took me a while to get this part to work. At first I had the read-schema code up beside the other global.settings.get_boolean at line 112 in the AppSwitcher.prototype._init: function(binding). But it took me a while to figure out the scoping of the variable was not correct for my needs. Reading the gsetting schema in the prototype did not set the variable for the function at line 73, function getWindowsForBinding(binding).

I also had to learn about the gsettings schema. I’ve dabbled with dconf before. But apparently adding a new key is a little more complicated that just

dconf load /org/cinnamon <<EOF
alttab-switcher-show-all-workspaces true

I learned that for gsettings you have to modify the xml-defined schema. I found it at /usr/share/glib-2.0/schemas/org.cinnamon.gschema.xml. My addition is pretty basic, at lines 541-545.

    <key type="b" name="alttab-switcher-show-all-workspaces">
      <_summary>Show all windows from all workspaces</_summary>

I also found file /usr/share/cinnamon/cinnamon-settings/modules/cs_windows.py and added the widget for this setting.

            widget = GSettingsSwitch(_("Show windows from all workspaces"), "org.cinnamon", "alttab-switcher-show-all-workspaces")

So I made my changes and then restarted Cinnamon. Still no go. After a lot of searching, I finally found the important part: I needed to run glib-compile-schemas!

pushd /usr/share/glib-2.0/schemas; glib-compile-schemas .; popd;

Now I finally had success! I submitted pull request #6938 and within a day my changes were approved and merged.

The commit as a patch

diff --git a/data/org.cinnamon.gschema.xml.in b/data/org.cinnamon.gschema.xml.in
index 71e09aca..17fe5dc4 100644
--- a/data/org.cinnamon.gschema.xml.in
+++ b/data/org.cinnamon.gschema.xml.in
@@ -538,6 +538,11 @@
       <_description>Duration of the effect (in milliseconds)</_description>
+    <key type="b" name="alttab-switcher-show-all-workspaces">
+      <default>false</default>
+      <_summary>Show all windows from all workspaces</_summary>
+    </key>
     <key name="bring-windows-to-current-workspace" type="b">
       <summary>Brings windows requiring attention to the current workspace</summary>
diff --git a/files/usr/share/cinnamon/cinnamon-settings/modules/cs_windows.py b/files/usr/share/cinnamon/cinnamon-settings/modules/cs_windows.py
index 4875346e..080026ab 100755
--- a/files/usr/share/cinnamon/cinnamon-settings/modules/cs_windows.py
+++ b/files/usr/share/cinnamon/cinnamon-settings/modules/cs_windows.py
@@ -129,6 +129,9 @@ class Module:
             widget = GSettingsSpinButton(_("Delay before displaying the alt-tab switcher"), "org.cinnamon", "alttab-switcher-delay", units=_("milliseconds"), mini=0, maxi=1000, step=50, page=150)
+            widget = GSettingsSwitch(_("Show windows from all workspaces"), "org.cinnamon", "alttab-switcher-show-all-workspaces")
+            settings.add_row(widget)
 class TitleBarButtonsOrderSelector(SettingsBox):
     def __init__(self):
         self.schema = "org.cinnamon.muffin"
diff --git a/js/ui/appSwitcher/appSwitcher.js b/js/ui/appSwitcher/appSwitcher.js
index f161350c..d36d3bf2 100644
--- a/js/ui/appSwitcher/appSwitcher.js
+++ b/js/ui/appSwitcher/appSwitcher.js
@@ -70,7 +70,10 @@ function getWindowsForBinding(binding) {
             // Switch between windows of current workspace
-            windows = windows.filter( matchWorkspace, global.screen.get_active_workspace() );
+            this._showAllWorkspaces = global.settings.get_boolean("alttab-switcher-show-all-workspaces");
+            if (!this._showAllWorkspaces) {
+                windows = windows.filter( matchWorkspace, global.screen.get_active_workspace() );
+            }



  1. Need to use glib-compile-schemas https://developer.gnome.org/gio/stable/GSettings.html
  2. https://developer.gnome.org/GSettings/

I am now an open source contributor!


I use open-source software every day, since November 2015. That was the year of Linux on the Desktop for me. I picked as my desktop environment Cinnamon.

I normally don’t use virtual desktops or “workspaces,” but on one laptop I was for a while. It was actually a KDE Plasma 5 installation, which reinforced my plans to stick to Cinnamon as my heavyweight DE. However, the KDE Plasma virtual workspaces worked fine, and provided all sorts of options for the window list and alt-tab switcher for listing windows across all the workspaces. Cinnamon did not have such an offering, so when I finally replaced KDE with Cinnamon on that workstation, I just reverted to my single-workspace workflow.

I told someone online (probably in the #korora channel at irc.freenode.net) that I was willing to pay money for Cinnamon to provide a window list option for displaying the windows from all workspaces. Well, as of October 2, I guess I owe myself $50.

Check out my merged pull request to Cinnamon! I added the feature, as a boolean setting, to the mainline Cinnamon window list applet. So eventually my option will be included in the Fedora Cinnamon build down the line. For the time being, though, I’m going to continue to use my separate applet that provides my feature.