Getting visual feedback of workspace switch in xfce

Solution 1:

I wrote a small code that shows a notification on workspace switch action. This code requires libnotify and libwnck

To compile it use the command:

gcc -O2 -o wsnd `pkg-config  --cflags --libs libnotify --libs libwnck` wsn.c

If you found compiling errors with above command, try this one:

gcc -O2 -DWNCK_I_KNOW_THIS_IS_UNSTABLE -o wsnd `pkg-config  --cflags --libs libnotify --libs libwnck-1.0` wsn.c

To test it from a terminal: ./wsnd

Include it as XFCE startup application: In XFCE you need to add it as startup applicaion on settings-manager->session and startup -> Application Autostart

The code:

//////////////////////////////////////////////////////////////////////////////////////
// Workspace Switch Notifier                                                        //
// Shows a OSD with workspace name on workspace switching action                    //
//                                                                                  //
// wsn.c -                                                                          //
//                                                                                  //
// Authors:                                                                         //
//    Isaac Maia Pessoa                                                             //
//                                                                                  //
// This program is free software: you can redistribute it and/or modify it          //
// under the terms of the GNU General Public License version 3, as published        //
// by the Free Software Foundation.                                                 //
//                                                                                  //
// This program is distributed in the hope that it will be useful, but              //
// WITHOUT ANY WARRANTY; without even the implied warranties of                     //
// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR               //
// PURPOSE.  See the GNU General Public License for more details.                   //
//                                                                                  //
// You should have received a copy of the GNU General Public License along          //
// with this program.  If not, see <http://www.gnu.org/licenses/>.                  //
//////////////////////////////////////////////////////////////////////////////////////

#include <libnotify/notify.h>
#include <libwnck/libwnck.h>

#define N_SUMMARY "Workspace Changed"
#define N_ICON    "dialog-information"
#define N_APPNAME "workspace switch notifier"
#define N_TIMEOUT 2000 /*2000ms = 2s */

static NotifyNotification * m_notification = NULL;

static void
on_active_workspace_changed (WnckScreen    *screen,
                             WnckWorkspace *space,
                             gpointer      data)
{

  WnckWorkspace * active_workspace = wnck_screen_get_active_workspace(screen);
  const char * w_name = wnck_workspace_get_name (active_workspace);

  notify_notification_update(m_notification, N_SUMMARY, w_name, N_ICON);
  notify_notification_show(m_notification, NULL);
}

int main(int argc, char ** argv)
{

   GMainLoop *loop;   
   WnckScreen *screen;

   if (notify_init(N_APPNAME))
       m_notification = notify_notification_new(N_SUMMARY, "" , N_ICON);
   else
       fprintf(stderr, "Failed to init notifications\n");
   notify_notification_set_timeout(m_notification, N_TIMEOUT);

   gdk_init (&argc, &argv);

   loop = g_main_loop_new (NULL, FALSE);
   screen = wnck_screen_get_default();

   g_signal_connect (screen, "active-workspace-changed",
                    G_CALLBACK (on_active_workspace_changed), NULL);

   g_main_loop_run (loop);

   g_main_loop_unref (loop);    

   return 0;
}

Solution 2:

I've modified Isaac Pessoa's answer for my own preferences. Instead of showing a notification on workspace changed, this briefly shows a hidden Xfce panel with the workspace switcher widget.

Here's what it looks like while switching workspaces: example

Save this file as wschanged.c:

#include <libwnck/libwnck.h>
#include <stdlib.h>

static void
on_active_workspace_changed (WnckScreen    *screen,
                             WnckWorkspace *space,
                             gpointer      data)
{
    // Executes a script on workspace change
    system ("~/.workspace-changed");
}

int main(int argc, char ** argv)
{

   GMainLoop *loop;   
   WnckScreen *screen;

   gdk_init (&argc, &argv);

   loop = g_main_loop_new (NULL, FALSE);
   screen = wnck_screen_get_default();

   g_signal_connect (screen, "active-workspace-changed",
                    G_CALLBACK (on_active_workspace_changed), NULL);

   g_main_loop_run (loop);
   g_main_loop_unref (loop);    

   return 0;
}

Now create a new Xfce panel anywhere on the edge of your screen and set it to auto-hide. Add the workspace switcher widget. Make a note of the panel number as displayed in the drop-down menu of the panel preferences window.

Make a .workspace-changed file in your home directory, replacing < P_NUMBER > with the panel number that you just created. Make sure this file is executable! (chmod +x .workspace-changed)

#!/bin/sh

# Show the auto-hidden workspace panel for a moment, then set it to autohide again
xfconf-query -c xfce4-panel -p /panels/panel-<P_NUMBER>/autohide -t bool -s false
xfconf-query -c xfce4-panel -p /panels/panel-<P_NUMBER>/autohide -t bool -s true

Now compile with:

gcc -O2 -DWNCK_I_KNOW_THIS_IS_UNSTABLE -o wschanged `pkg-config  --cflags --libs libwnck-1.0` wschanged.c

Test it in your terminal (./wschanged) to make sure everything looks right. When satisfied, add the program as an Xfce startup application: Settings -> Session and Startup -> Application Autostart.

Solution 3:

Most of the answers are 5 years old and as of xubuntu 18.04 don't work anymore. I've put together an updated version of zspotter's answer that runs on 18.04. For simplicity I'll assume that all files are located in the home directory, you can easily adapt the scripts to a different folder.

First create a file called wschanged.c with this contents:

#include <libwnck/libwnck.h>
#include <stdlib.h>

static void
on_active_workspace_changed (WnckScreen    *screen,
                             WnckWorkspace *space,
                             gpointer      data)
{
    // Executes a script on workspace change
    system ("~/.workspace-changed");
}

int main(int argc, char ** argv)
{

   GMainLoop *loop;   
   WnckScreen *screen;

   gdk_init (&argc, &argv);

   loop = g_main_loop_new (NULL, FALSE);
   screen = wnck_screen_get_default();

   g_signal_connect (screen, "active-workspace-changed",
                    G_CALLBACK (on_active_workspace_changed), NULL);

   g_main_loop_run (loop);
   g_main_loop_unref (loop);    

   return 0;
}

Second, create a new Xfce panel anywhere on the edge of your screen and set it to auto-hide. Add the workspace switcher widget. Make a note of the panel number as displayed in the drop-down menu of the panel preferences window, in our example the panel number is 2, adjust accordingly.

Third, here things start to get different, create another script in the same folder called wschanged.sh with this contents (remember to set it as executable with rightclick -> properties-> set as executable, or chmod +x .wschanged.sh in a terminal):

#!/bin/sh

# Show the auto-hidden workspace panel for a moment, then set it to autohide again
xfconf-query -c xfce4-panel -p /panels/panel-2/autohide-behavior -s 1
xfconf-query -c xfce4-panel -p /panels/panel-2/autohide-behavior -s 2

The panels no longer have an autohide property but an autohide-behavior property and thus the adjustments in the script.

Fourth, we have to compile the .c file, the commands in previous answers don't work anymore, as suggested here use:

gcc -O2 -DWNCK_I_KNOW_THIS_IS_UNSTABLE -o wschanged `pkg-config --cflags libwnck-3.0` wschanged.c `pkg-config --libs libwnck-3.0`

If you get an error install libwnck-3-dev with sudo apt install libwnck-3-dev.

You can now test the script with ./wschanged (place yourself in the same directory as the executable). You can also now set to run the command at startup.