Where have my Konqueror favicons gone?

I upgraded to KDE 4.13.0 recently only to find that Konqueror no longer displayed some of the favicons, neither in the Bookmarks menu nor in the URL address bar. It seems this is a known KDE bug first reported in 2007 (Bug 153049 – Konqueror from KDE4 doesn’t load some favicons) although apparently it does not affect many users, which is why it still has not been fixed, I suppose.

In 2010 a KDE user reported in the KDE Community Forums thread Konqueror favicons again the steps he used to fix the problem in his installation, but he did not give the precise file names and paths of the files he deleted. In any case, I did not fancy deleting any sockets.

I tried various things, such as exporting and reimporting bookmarks in Konqueror, but was unable to get the missing favicons to display again. In the end I accepted I would have to lose all my bookmarks and decided to reinstall Konqueror. However, not all files are removed when a package is uninstalled, so I made sure everything was gone as follows:

1. Uninstall Konqueror

# emerge -C konqueror

2. Delete left-over directories and files relating to Konqueror

# rm -rf /home/fitzcarraldo/.kde4/share/apps/konqueror/
# rm /home/fitzcarraldo/.kde4/share/config/konq*

3. Log out of KDE and switch to a VT (virtual terminal, a.k.a. console)

# rm /var/tmp/kdecache-fitzcarraldo/favicons/*
# rm /var/tmp/kdecache-fitzcarraldo/icon-cache.kcache

4. Log in to KDE again and re-install Konqueror

# emerge -1v konqueror

5. Launch Konqueror and bookmark all your favourite Web sites.

That will get favicons working again in Konqueror, but what a hassle. KDE developers, please fix this old bug (no. 153049)!

Using KWrite to find and replace a character with a CRLF (Carriage Return/Line Feed)

Occasionally I need to edit a long string and replace the space character with a CRLF and some text. Even though I was sure the KDE editor KWrite could do that, I had never bothered to find out how. Today I finally bit the bullet. It’s not difficult, of course. To show you how it is done, I’ll give an actual example…

I wanted to edit in KWrite the single line of text shown below. (Not that it’s relevant to the subject of this post, but the line was a command to the Gentoo package manager to install a long list of packages, and I wanted to split it into separate commands in order to install each package individually.)

emerge -vD1 --backtrack=30 media-video/dvdrip:0 dev-vcs/git:0 dev-vcs/subversion:0 net-print/foomatic-db-engine:0 app-antivirus/clamtk:0 dev-perl/XML-SAX:0 dev-perl/X11-Protocol:0 dev-perl/Goo-Canvas:0 dev-perl/Readonly:0 dev-perl/File-Find-Rule:0 dev-perl/Net-SSLeay:0 dev-perl/XML-LibXML:0 dev-perl/HTTP-Message:0 dev-perl/Digest-SHA1:0 dev-perl/XML-XPath:0 dev-perl/File-Which:0 dev-perl/Authen-SASL:0 dev-perl/glib-perl:0 dev-perl/prefork:0 dev-perl/IO-Socket-SSL:0 dev-perl/Exception-Class:0 dev-perl/Proc-Simple:0 dev-perl/WWW-Mechanize:0 dev-perl/gnome2-canvas:0 dev-perl/gnome2-vfs-perl:0 dev-perl/IO-String:0 dev-perl/HTML-Tagset:0 dev-perl/Carp-Clan:0 dev-perl/Pod-Spell:0 dev-perl/Sane:0 dev-perl/TermReadKey:0 dev-perl/HTTP-Date:0 dev-perl/Encode-Locale:0 dev-perl/Event-RPC:0 dev-perl/File-HomeDir:0 dev-perl/Bit-Vector:0 dev-perl/gnome2-wnck:0 dev-perl/File-Copy-Recursive:0 dev-perl/Text-Unidecode:0 dev-perl/Unicode-EastAsianWidth:0 dev-perl/extutils-pkgconfig:0 dev-perl/Clone:0 dev-perl/Event-ExecFlow:0 dev-perl/B-Keywords:0 dev-perl/PDF-API2:0 dev-perl/HTTP-Negotiate:0 dev-perl/HTML-Form:0 dev-perl/extutils-depends:0 dev-perl/PlRPC:0 dev-perl/libwww-perl:0 dev-perl/gtk2-perl:0 dev-perl/File-MimeInfo:0 dev-perl/Font-TTF:0 dev-perl/libintl-perl:0 dev-perl/List-MoreUtils:0 dev-perl/Log-Log4perl:0 dev-perl/XML-DOM:0 dev-perl/HTML-Parser:0 dev-perl/Try-Tiny:0 dev-perl/XML-Twig:0 dev-perl/Gtk2-Ex-Simple-List:0 dev-perl/LWP-MediaTypes:0 dev-perl/LWP-Protocol-https:0 dev-perl/XML-Simple:0 dev-perl/Pango:0 dev-perl/set-scalar:0 dev-perl/Gtk2-Unique:0 dev-perl/Params-Util:0 dev-perl/Net-Daemon:0 dev-perl/GSSAPI:0 dev-perl/XML-NamespaceSupport:0 dev-perl/PPI:0 dev-perl/Proc-ProcessTable:0 dev-perl/String-Format:0 dev-perl/Date-Calc:0 dev-perl/XML-Parser:0 dev-perl/Email-Address:0 dev-perl/Class-Data-Inheritable:0 dev-perl/Email-Simple:0 dev-perl/JSON:0 dev-perl/gnome2-perl:0 dev-perl/XML-SAX-Base:0 dev-perl/Net-SMTP-SSL:0 dev-perl/Gtk2-ImageView:0 dev-perl/IO-HTML:0 dev-perl/WWW-RobotRules:0 dev-perl/Digest-HMAC:0 dev-perl/HTTP-Cookies:0 dev-perl/DBI:0 dev-perl/URI:0 dev-perl/Text-Iconv:0 dev-perl/gtk2-ex-formfactory:0 dev-perl/Email-Date-Format:0 dev-perl/libxml-perl:0 dev-perl/XML-SAX-Writer:0 dev-perl/XML-Filter-BufferText:0 dev-perl/Number-Compare:0 dev-perl/XML-RegExp:0 dev-perl/Email-LocalDelivery:0 dev-perl/config-general:0 dev-perl/HTTP-Daemon:0 dev-perl/File-Listing:0 dev-perl/Devel-StackTrace:0 dev-perl/Set-IntSpan:0 dev-perl/Cairo:0 dev-perl/Email-FolderType:0 dev-perl/XML-Handler-YAWriter:0 dev-perl/Archive-Zip:0 dev-perl/Net-DBus:0 dev-perl/DBD-mysql:0 dev-perl/AnyEvent:0 dev-perl/perltidy:0 dev-perl/Locale-gettext:0 dev-perl/Sort-Naturally:0 dev-perl/Net-HTTP:0 dev-perl/Perl-Critic:0 media-gfx/gscan2pdf:0 media-libs/exiftool:0 perl-core/CPAN-Meta-Requirements:0 virtual/perl-CPAN-Meta-Requirements:0 perl-core/IPC-Cmd:0 virtual/perl-IPC-Cmd:0 perl-core/Storable:0 virtual/perl-Storable:0 perl-core/File-Spec:0 virtual/perl-File-Spec:0 perl-core/CPAN-Meta:0 virtual/perl-CPAN-Meta:0 perl-core/Getopt-Long:0 virtual/perl-Getopt-Long:0 perl-core/Locale-Maketext-Simple:0 virtual/perl-Locale-Maketext-Simple:0 perl-core/ExtUtils-Manifest:0 virtual/perl-ExtUtils-Manifest:0 perl-core/Pod-Simple:0 virtual/perl-Pod-Simple:0 perl-core/CPAN-Meta-YAML:0 virtual/perl-CPAN-Meta-YAML:0 perl-core/Encode:0 virtual/perl-Encode:0 perl-core/Compress-Raw-Bzip2:0 virtual/perl-Compress-Raw-Bzip2:0 perl-core/Module-Load:0 virtual/perl-Module-Load:0 perl-core/Archive-Tar:0 virtual/perl-Archive-Tar:0 perl-core/Scalar-List-Utils:0 virtual/perl-Scalar-List-Utils:0 perl-core/ExtUtils-CBuilder:0 virtual/perl-ExtUtils-CBuilder:0 perl-core/Parse-CPAN-Meta:0 virtual/perl-Parse-CPAN-Meta:0 perl-core/version:0 virtual/perl-version:0 perl-core/Digest-SHA:0 virtual/perl-Digest-SHA:0 perl-core/Module-Load-Conditional:0 virtual/perl-Module-Load-Conditional:0 perl-core/Compress-Raw-Zlib:0 virtual/perl-Compress-Raw-Zlib:0 perl-core/ExtUtils-Install:0 virtual/perl-ExtUtils-Install:0 perl-core/IO:0 virtual/perl-IO:0 perl-core/Time-Local:0 virtual/perl-Time-Local:0 perl-core/Module-CoreList:0 virtual/perl-Module-CoreList:0 perl-core/Digest-MD5:0 virtual/perl-Digest-MD5:0 perl-core/JSON-PP:0 virtual/perl-JSON-PP:0 perl-core/ExtUtils-ParseXS:0 virtual/perl-ExtUtils-ParseXS:0 perl-core/File-Temp:0 virtual/perl-File-Temp:0 perl-core/Params-Check:0 virtual/perl-Params-Check:0 perl-core/Module-Metadata:0 virtual/perl-Module-Metadata:0 perl-core/Sys-Syslog:0 virtual/perl-Sys-Syslog:0 perl-core/IO-Compress:0 virtual/perl-IO-Compress:0 perl-core/Test-Harness:0 virtual/perl-Test-Harness:0

With the above line of text in a KWrite window, I did the following:

1. I selected Edit > Replace… from the KWrite menu.

2. At the bottom of the KWrite window, I changed the Mode from ‘Plain text’ to ‘Regular expression’.

3. I clicked in the ‘Find’ box and pressed the Space bar to enter a space character.

4. I clicked in the ‘Replace’ box and entered the following text (note that there is ‘\n’ at the beginning and a space at the end):

\nemerge -vD1 --backtrack=30 

The ‘\n‘ represents a CRLF (Carriage Return plus Line Feed).

5. I ticked ‘Selection only’.

6. With the mouse I selected the text in which I wanted to make the replacement, i.e. I selected from (and including) the space following the first package (media-video/dvdrip:0) all the way to the end of the line.

7. I clicked on ‘Replace All’.

The result looked like this:

emerge -vD1 --backtrack=30 media-video/dvdrip:0
emerge -vD1 --backtrack=30 dev-vcs/git:0
emerge -vD1 --backtrack=30 dev-vcs/subversion:0
emerge -vD1 --backtrack=30 net-print/foomatic-db-engine:0
emerge -vD1 --backtrack=30 app-antivirus/clamtk:0
emerge -vD1 --backtrack=30 dev-perl/XML-SAX:0
emerge -vD1 --backtrack=30 dev-perl/X11-Protocol:0
emerge -vD1 --backtrack=30 dev-perl/Goo-Canvas:0
emerge -vD1 --backtrack=30 dev-perl/Readonly:0
emerge -vD1 --backtrack=30 dev-perl/File-Find-Rule:0
emerge -vD1 --backtrack=30 dev-perl/Net-SSLeay:0
emerge -vD1 --backtrack=30 dev-perl/XML-LibXML:0
emerge -vD1 --backtrack=30 dev-perl/HTTP-Message:0
emerge -vD1 --backtrack=30 dev-perl/Digest-SHA1:0
emerge -vD1 --backtrack=30 dev-perl/XML-XPath:0
emerge -vD1 --backtrack=30 dev-perl/File-Which:0
emerge -vD1 --backtrack=30 dev-perl/Authen-SASL:0
emerge -vD1 --backtrack=30 dev-perl/glib-perl:0
emerge -vD1 --backtrack=30 dev-perl/prefork:0
emerge -vD1 --backtrack=30 dev-perl/IO-Socket-SSL:0
emerge -vD1 --backtrack=30 dev-perl/Exception-Class:0
emerge -vD1 --backtrack=30 dev-perl/Proc-Simple:0
emerge -vD1 --backtrack=30 dev-perl/WWW-Mechanize:0
emerge -vD1 --backtrack=30 dev-perl/gnome2-canvas:0
emerge -vD1 --backtrack=30 dev-perl/gnome2-vfs-perl:0
emerge -vD1 --backtrack=30 dev-perl/IO-String:0
emerge -vD1 --backtrack=30 dev-perl/HTML-Tagset:0
emerge -vD1 --backtrack=30 dev-perl/Carp-Clan:0
emerge -vD1 --backtrack=30 dev-perl/Pod-Spell:0
emerge -vD1 --backtrack=30 dev-perl/Sane:0
emerge -vD1 --backtrack=30 dev-perl/TermReadKey:0
emerge -vD1 --backtrack=30 dev-perl/HTTP-Date:0
emerge -vD1 --backtrack=30 dev-perl/Encode-Locale:0
emerge -vD1 --backtrack=30 dev-perl/Event-RPC:0
emerge -vD1 --backtrack=30 dev-perl/File-HomeDir:0
emerge -vD1 --backtrack=30 dev-perl/Bit-Vector:0
emerge -vD1 --backtrack=30 dev-perl/gnome2-wnck:0
emerge -vD1 --backtrack=30 dev-perl/File-Copy-Recursive:0
emerge -vD1 --backtrack=30 dev-perl/Text-Unidecode:0
emerge -vD1 --backtrack=30 dev-perl/Unicode-EastAsianWidth:0
emerge -vD1 --backtrack=30 dev-perl/extutils-pkgconfig:0
emerge -vD1 --backtrack=30 dev-perl/Clone:0
emerge -vD1 --backtrack=30 dev-perl/Event-ExecFlow:0
emerge -vD1 --backtrack=30 dev-perl/B-Keywords:0
emerge -vD1 --backtrack=30 dev-perl/PDF-API2:0
emerge -vD1 --backtrack=30 dev-perl/HTTP-Negotiate:0
emerge -vD1 --backtrack=30 dev-perl/HTML-Form:0
emerge -vD1 --backtrack=30 dev-perl/extutils-depends:0
emerge -vD1 --backtrack=30 dev-perl/PlRPC:0
emerge -vD1 --backtrack=30 dev-perl/libwww-perl:0
emerge -vD1 --backtrack=30 dev-perl/gtk2-perl:0
emerge -vD1 --backtrack=30 dev-perl/File-MimeInfo:0
emerge -vD1 --backtrack=30 dev-perl/Font-TTF:0
emerge -vD1 --backtrack=30 dev-perl/libintl-perl:0
emerge -vD1 --backtrack=30 dev-perl/List-MoreUtils:0
emerge -vD1 --backtrack=30 dev-perl/Log-Log4perl:0
emerge -vD1 --backtrack=30 dev-perl/XML-DOM:0
emerge -vD1 --backtrack=30 dev-perl/HTML-Parser:0
emerge -vD1 --backtrack=30 dev-perl/Try-Tiny:0
emerge -vD1 --backtrack=30 dev-perl/XML-Twig:0
emerge -vD1 --backtrack=30 dev-perl/Gtk2-Ex-Simple-List:0
emerge -vD1 --backtrack=30 dev-perl/LWP-MediaTypes:0
emerge -vD1 --backtrack=30 dev-perl/LWP-Protocol-https:0
emerge -vD1 --backtrack=30 dev-perl/XML-Simple:0
emerge -vD1 --backtrack=30 dev-perl/Pango:0
emerge -vD1 --backtrack=30 dev-perl/set-scalar:0
emerge -vD1 --backtrack=30 dev-perl/Gtk2-Unique:0
emerge -vD1 --backtrack=30 dev-perl/Params-Util:0
emerge -vD1 --backtrack=30 dev-perl/Net-Daemon:0
emerge -vD1 --backtrack=30 dev-perl/GSSAPI:0
emerge -vD1 --backtrack=30 dev-perl/XML-NamespaceSupport:0
emerge -vD1 --backtrack=30 dev-perl/PPI:0
emerge -vD1 --backtrack=30 dev-perl/Proc-ProcessTable:0
emerge -vD1 --backtrack=30 dev-perl/String-Format:0
emerge -vD1 --backtrack=30 dev-perl/Date-Calc:0
emerge -vD1 --backtrack=30 dev-perl/XML-Parser:0
emerge -vD1 --backtrack=30 dev-perl/Email-Address:0
emerge -vD1 --backtrack=30 dev-perl/Class-Data-Inheritable:0
emerge -vD1 --backtrack=30 dev-perl/Email-Simple:0
emerge -vD1 --backtrack=30 dev-perl/JSON:0
emerge -vD1 --backtrack=30 dev-perl/gnome2-perl:0
emerge -vD1 --backtrack=30 dev-perl/XML-SAX-Base:0
emerge -vD1 --backtrack=30 dev-perl/Net-SMTP-SSL:0
emerge -vD1 --backtrack=30 dev-perl/Gtk2-ImageView:0
emerge -vD1 --backtrack=30 dev-perl/IO-HTML:0
emerge -vD1 --backtrack=30 dev-perl/WWW-RobotRules:0
emerge -vD1 --backtrack=30 dev-perl/Digest-HMAC:0
emerge -vD1 --backtrack=30 dev-perl/HTTP-Cookies:0
emerge -vD1 --backtrack=30 dev-perl/DBI:0
emerge -vD1 --backtrack=30 dev-perl/URI:0
emerge -vD1 --backtrack=30 dev-perl/Text-Iconv:0
emerge -vD1 --backtrack=30 dev-perl/gtk2-ex-formfactory:0
emerge -vD1 --backtrack=30 dev-perl/Email-Date-Format:0
emerge -vD1 --backtrack=30 dev-perl/libxml-perl:0
emerge -vD1 --backtrack=30 dev-perl/XML-SAX-Writer:0
emerge -vD1 --backtrack=30 dev-perl/XML-Filter-BufferText:0
emerge -vD1 --backtrack=30 dev-perl/Number-Compare:0
emerge -vD1 --backtrack=30 dev-perl/XML-RegExp:0
emerge -vD1 --backtrack=30 dev-perl/Email-LocalDelivery:0
emerge -vD1 --backtrack=30 dev-perl/config-general:0
emerge -vD1 --backtrack=30 dev-perl/HTTP-Daemon:0
emerge -vD1 --backtrack=30 dev-perl/File-Listing:0
emerge -vD1 --backtrack=30 dev-perl/Devel-StackTrace:0
emerge -vD1 --backtrack=30 dev-perl/Set-IntSpan:0
emerge -vD1 --backtrack=30 dev-perl/Cairo:0
emerge -vD1 --backtrack=30 dev-perl/Email-FolderType:0
emerge -vD1 --backtrack=30 dev-perl/XML-Handler-YAWriter:0
emerge -vD1 --backtrack=30 dev-perl/Archive-Zip:0
emerge -vD1 --backtrack=30 dev-perl/Net-DBus:0
emerge -vD1 --backtrack=30 dev-perl/DBD-mysql:0
emerge -vD1 --backtrack=30 dev-perl/AnyEvent:0
emerge -vD1 --backtrack=30 dev-perl/perltidy:0
emerge -vD1 --backtrack=30 dev-perl/Locale-gettext:0
emerge -vD1 --backtrack=30 dev-perl/Sort-Naturally:0
emerge -vD1 --backtrack=30 dev-perl/Net-HTTP:0
emerge -vD1 --backtrack=30 dev-perl/Perl-Critic:0
emerge -vD1 --backtrack=30 media-gfx/gscan2pdf:0
emerge -vD1 --backtrack=30 media-libs/exiftool:0
emerge -vD1 --backtrack=30 perl-core/CPAN-Meta-Requirements:0
emerge -vD1 --backtrack=30 virtual/perl-CPAN-Meta-Requirements:0
emerge -vD1 --backtrack=30 perl-core/IPC-Cmd:0
emerge -vD1 --backtrack=30 virtual/perl-IPC-Cmd:0
emerge -vD1 --backtrack=30 perl-core/Storable:0
emerge -vD1 --backtrack=30 virtual/perl-Storable:0
emerge -vD1 --backtrack=30 perl-core/File-Spec:0
emerge -vD1 --backtrack=30 virtual/perl-File-Spec:0
emerge -vD1 --backtrack=30 perl-core/CPAN-Meta:0
emerge -vD1 --backtrack=30 virtual/perl-CPAN-Meta:0
emerge -vD1 --backtrack=30 perl-core/Getopt-Long:0
emerge -vD1 --backtrack=30 virtual/perl-Getopt-Long:0
emerge -vD1 --backtrack=30 perl-core/Locale-Maketext-Simple:0
emerge -vD1 --backtrack=30 virtual/perl-Locale-Maketext-Simple:0
emerge -vD1 --backtrack=30 perl-core/ExtUtils-Manifest:0
emerge -vD1 --backtrack=30 virtual/perl-ExtUtils-Manifest:0
emerge -vD1 --backtrack=30 perl-core/Pod-Simple:0
emerge -vD1 --backtrack=30 virtual/perl-Pod-Simple:0
emerge -vD1 --backtrack=30 perl-core/CPAN-Meta-YAML:0
emerge -vD1 --backtrack=30 virtual/perl-CPAN-Meta-YAML:0
emerge -vD1 --backtrack=30 perl-core/Encode:0
emerge -vD1 --backtrack=30 virtual/perl-Encode:0
emerge -vD1 --backtrack=30 perl-core/Compress-Raw-Bzip2:0
emerge -vD1 --backtrack=30 virtual/perl-Compress-Raw-Bzip2:0
emerge -vD1 --backtrack=30 perl-core/Module-Load:0
emerge -vD1 --backtrack=30 virtual/perl-Module-Load:0
emerge -vD1 --backtrack=30 perl-core/Archive-Tar:0
emerge -vD1 --backtrack=30 virtual/perl-Archive-Tar:0
emerge -vD1 --backtrack=30 perl-core/Scalar-List-Utils:0
emerge -vD1 --backtrack=30 virtual/perl-Scalar-List-Utils:0
emerge -vD1 --backtrack=30 perl-core/ExtUtils-CBuilder:0
emerge -vD1 --backtrack=30 virtual/perl-ExtUtils-CBuilder:0
emerge -vD1 --backtrack=30 perl-core/Parse-CPAN-Meta:0
emerge -vD1 --backtrack=30 virtual/perl-Parse-CPAN-Meta:0
emerge -vD1 --backtrack=30 perl-core/version:0
emerge -vD1 --backtrack=30 virtual/perl-version:0
emerge -vD1 --backtrack=30 perl-core/Digest-SHA:0
emerge -vD1 --backtrack=30 virtual/perl-Digest-SHA:0
emerge -vD1 --backtrack=30 perl-core/Module-Load-Conditional:0
emerge -vD1 --backtrack=30 virtual/perl-Module-Load-Conditional:0
emerge -vD1 --backtrack=30 perl-core/Compress-Raw-Zlib:0
emerge -vD1 --backtrack=30 virtual/perl-Compress-Raw-Zlib:0
emerge -vD1 --backtrack=30 perl-core/ExtUtils-Install:0
emerge -vD1 --backtrack=30 virtual/perl-ExtUtils-Install:0
emerge -vD1 --backtrack=30 perl-core/IO:0
emerge -vD1 --backtrack=30 virtual/perl-IO:0
emerge -vD1 --backtrack=30 perl-core/Time-Local:0
emerge -vD1 --backtrack=30 virtual/perl-Time-Local:0
emerge -vD1 --backtrack=30 perl-core/Module-CoreList:0
emerge -vD1 --backtrack=30 virtual/perl-Module-CoreList:0
emerge -vD1 --backtrack=30 perl-core/Digest-MD5:0
emerge -vD1 --backtrack=30 virtual/perl-Digest-MD5:0
emerge -vD1 --backtrack=30 perl-core/JSON-PP:0
emerge -vD1 --backtrack=30 virtual/perl-JSON-PP:0
emerge -vD1 --backtrack=30 perl-core/ExtUtils-ParseXS:0
emerge -vD1 --backtrack=30 virtual/perl-ExtUtils-ParseXS:0
emerge -vD1 --backtrack=30 perl-core/File-Temp:0
emerge -vD1 --backtrack=30 virtual/perl-File-Temp:0
emerge -vD1 --backtrack=30 perl-core/Params-Check:0
emerge -vD1 --backtrack=30 virtual/perl-Params-Check:0
emerge -vD1 --backtrack=30 perl-core/Module-Metadata:0
emerge -vD1 --backtrack=30 virtual/perl-Module-Metadata:0
emerge -vD1 --backtrack=30 perl-core/Sys-Syslog:0
emerge -vD1 --backtrack=30 virtual/perl-Sys-Syslog:0
emerge -vD1 --backtrack=30 perl-core/IO-Compress:0
emerge -vD1 --backtrack=30 virtual/perl-IO-Compress:0
emerge -vD1 --backtrack=30 perl-core/Test-Harness:0
emerge -vD1 --backtrack=30 virtual/perl-Test-Harness:0

That’s all there is to it. :-)

Installing the Windows version of Google Earth in WINE

Some Gentoo Linux users have reported that, although the native Linux release of Google Earth crashes, they can run the Windows version successfully under WINE. However, those users have also reported that the Windows installer for Google Earth did not work under WINE and so they copied the C:\Program Files\Google\Google Earth\ directory from a Windows PC to the virtual C:\ drive in their .wine directory (it would be ‘Program Files (x86)‘ in a 64-bit Windows installation, as Google Earth is a 32-bit application).

Now, if you download the Windows Google Earth installer from the Google Web site, what you get is a file GoogleEarthWin.exe that is 534.6 KiB in size (the size may vary depending on the release). However, you can instead download the Offline Installer using the following URL:

http://dl.google.com/earth/client/advanced/current/GoogleEarthWin.exe

and then you get a file GoogleEarthWin.exe that is 24.3 MiB in size (the size will vary depending on the release), which does run in WINE and does install the Windows version of Google Earth in WINE.

So, you might like to try that if you cannot run Google Earth in Linux but you have WINE installed. However, note that you will be wasting your time if the native Linux version of Google Earth crashes because of its incompatibility with the closed-source ATI or NVIDIA video driver. For example, Google Earth 7.1.2.2041 for Linux crashes on my main laptop using the 14.3_beta version of ati-drivers (AMD ATI Catalyst driver, a.k.a. FGLRX).

Anyway, if you want to install the Windows release of Google Earth under WINE here’s how to do it in a Konsole/Terminal window:

$ cd
$ export WINEPREFIX=$HOME/.wine-googleearth
$ export WINEARCH="win32"
$ winecfg
$ cd ./.wine-googleearth/drive_c/
$ wget http://dl.google.com/earth/client/advanced/current/GoogleEarthWin.exe
$ wine GoogleEarthWin.exe

And, to run it later:

$ env WINEPREFIX="/home/fitzcarraldo/.wine-googleearth" WINEARCH="win32" wine C:\\windows\\command\\start.exe /Unix /home/fitzcarraldo/.wine-googleearth/dosdevices/c:/users/fitzcarraldo/Start\ Menu/Programs/Google\ Earth/Google\ Earth.lnk

(Of course replace “fitzcarraldo” with your user name.)

But, as I wrote above, if the native Linux version of Google Earth crashes due to its incompatibility with the closed-source video driver (ATI or NVIDIA), it is highly unlikely the native Windows version will work under WINE.

Bypassing a corporate Web filter when using the command line

or ‘How to bypass a corporate Web filter and download YouTube videos via the command line’

One of the offices where I work uses a Web filter to block access to certain sites, such as YouTube. However, sometimes it is necessary to view blocked Web sites for work purposes. For example, these days a lot of companies or individuals post product reviews on YouTube that are useful for work purposes. In such cases I have used Tor to access the blocked sites in a Web browser such as Firefox, Chrome, Konqueror etc. See my post How to install and use Tor for anonymous browsing or to access country-restricted content from another country for details of how to set up and use Tor with a Web browser.

But sometimes I need to access blocked Web sites from the command line. For example, today I needed to download a YouTube video for work purposes, and I wanted to use youtube-dl to do it. The solution was simple…

First I launched vidalia and polipo as explained in the above-mentioned post on Tor, then I launched another Konsole/Terminal window and entered the commands shown below:

$ # First find out what resolutions are available for the video I want to download:
$ youtube-dl -F https://www.youtube.com/watch?v=T3Rr4CUoTSQ
Setting language
T3Rr4CUoTSQ: Downloading webpage
T3Rr4CUoTSQ: Downloading video info webpage
T3Rr4CUoTSQ: Extracting video information
[info] Available formats for T3Rr4CUoTSQ:
format code extension resolution note
140 m4a audio only DASH audio , audio@128k (worst)
160 mp4 192p DASH video
133 mp4 240p DASH video
134 mp4 360p DASH video
135 mp4 480p DASH video
136 mp4 720p DASH video
17 3gp 176x144
36 3gp 320x240
5 flv 400x240
43 webm 640x360
18 mp4 640x360
22 mp4 1280x720 (best)
$ # Now try to download the video at the resolution I want:
$ youtube-dl -f 22 -o Clevo_W230ST_overview.flv https://www.youtube.com/watch?v=T3Rr4CUoTSQ
Setting language
T3Rr4CUoTSQ: Downloading webpage
T3Rr4CUoTSQ: Downloading video info webpage
T3Rr4CUoTSQ: Extracting video information
ERROR: unable to download video data: HTTP Error 403: Forbidden

As you can see above, the corporate Web filter blocked youtube-dl from downloading the video.

So I informed the shell session about the local HTTP proxy (polipo) running on my laptop, by assigning and exporting the environment variable http_proxy using the following syntax:

export http_proxy=http://server-ip:port/

which in my case meant the following (refer to my article on Tor):

$ export http_proxy=http://127.0.0.1:8123/

and then I was able to download the video from YouTube despite the corporate Web filter:

$ youtube-dl -f 22 -o Clevo_W230ST_overview.flv https://www.youtube.com/watch?v=T3Rr4CUoTSQ
Setting language
T3Rr4CUoTSQ: Downloading webpage
T3Rr4CUoTSQ: Downloading video info webpage
T3Rr4CUoTSQ: Extracting video information
[download] Destination: Clevo_W230ST_overview.flv
[download] 100% of 100.23MiB in 05:50
$

Useful Reference: How To Use Proxy Server To Access Internet at Shell Prompt With http_proxy Variable

Fixing a problem with received video in Skype when using the AMD Catalyst (FGLRX) driver in Linux

Some users of Skype for Linux have reported that the bottom half of the received video image is corrupted in installations that use the closed-source video driver for ATI GPUs (the AMD Catalyst proprietary Linux driver, also known as the ‘FGLRX’ driver). One user described the lower half of the video image as “covered in small coloured squares like a chequer board”.

From what I have read in a few forums, it seems the problem does not occur when the open-source Radeon driver is used. My own experience corroborates that: I use the Radeon driver on one of my laptops, and received video in Skype is fine.

My main laptop has an AMD ATI Mobility Radeon HD 5650 GPU and I am using the Catalyst driver under Gentoo Linux. In this case there was a problem with received video in most Skype sessions. Either of the following effects usually occurred:

Snapshot 1 - Extract of received video image in Skype, showing an example of the corrupted image

Snapshot 1 - Extract of received video image in Skype, showing an example of the corrupted image

Snapshot 2 - Extract of received video image in Skype, showing another example of the corrupted image

Snapshot 2 - Extract of received video image in Skype, showing another example of the corrupted image

As shown in Snapshot 1, the lower half of the received video image was covered in a grid of thin green lines with areas tinged with purple, blue or green, whereas there was no grid of lines in the upper half of the image but some areas were tinged with red or blue.

As shown in Snapshot 2, the lower half of the received video image was covered in a grid of thin red lines, with a purple tinge in some areas, whereas there was no grid of lines in the upper half of the image, which looked reasonable but had some red-, green- or blue-tinged areas.

In all cases Skype’s thumbnail of my Webcam’s video image looked fine, and the person on the other end of the call said the video image received from me looked fine too.

Because of a bug in a previous version of the Catalyst driver a few years ago — see my blog posts Playing QuickTime videos in Firefox and Chromium + XVideo bug in AMD Catalyst 11.11 and 11.12 driver and AMD Catalyst for Linux driver 12.2 fixes the XVideo bug that crashed X.Org Server 1.11.x — I happen to know that Sykpe uses X11 overlays with the XVideo extension (xv), rather than using the OpenGL renderer (gl) or X11 with the SHM extension (x11). This made me wonder whether the use of XVideo with the Catalyst driver was causing the current problem. Unlike media players such as MPlayer and VLC, it is not possible to configure Skype to use gl or x11 instead of xv, so I thought it would not be possible to test whether the use of gl or x11 instead of xv would make a difference. Until, that is, I came upon a ‘trick’ posted by openSUSE user queequeg in 2009 during the period when an earlier version of the Catalyst driver had the aforementioned bug:

Skype Video Workaround for ATI

Anybody trying to make a video call with Skype and ATI fglrx drivers has had problems due to Skype using the “xv” video mode with the driver can’t handle. For anyone interested that is affected by this, there is a workaround:

1. Run the xvinfo command and look at the number of xv sessions available. Some cards have only 1, some have as many as 4. This is the number of xv occurances that the card can do at one time.
2. “Use up” all these xv sessions by opening videos in your favorite video player making sure to use xv for the video output. The videos can then be paused.
3. Once this (or they) are open, skype can be started and will default to X11 video and work properly with video calls.

I know this is a goofy way to get around this issue, but until fglrx can handle xv or skype allows an option to choose X11 for video render, I don’t know of any other way to do it.

(From what I hear, the 11.1 fglrx drivers can handle xv, but I haven’t confirmed this.)

So I tried his work-around. I had to launch four media players in order to use all available XVideo sessions. Lo and behold, when I launched Skype and made a video call the received video image was perfect. So it appeared that the Catalyst driver is not able to handle well the XVideo output from Skype. However, playing and pausing four videos every time I want to make a video call in Skype would hardly be practical, would it? And that is not the only downside: when I maximised a Firefox window during the Skype video call, my laptop spontaneously rebooted (I assume the X.Org server crashed).

I did also wonder whether just disabling compositing would solve the problem, so I disabled KWin Desktop Effects, but that didn’t make any difference.

I had also read in several forums that enabling or disabling the TexturedVideo and/or VideoOverlay options in the xorg.conf file have an effect on the video image produced by the Catalyst driver, but I could not find a post mentioning the use of either of those options to fix the specific problem I was seeing. So I decided not to pursue the xorg.conf route.

In my searches of the Web I came across a post somewhere that mentioned using GTK+ UVC Viewer (guvcview) to adjust video properties and improve video in Skype. I thought guvcview was only for adjusting the video image from a Webcam connected to my machine, i.e. adjusting the outgoing video image, and would not have any effect on received video. Nevertheless, I decided to install and launch guvcview to see if I could adjust both incoming and outgoing video properties. To my surprise, guvcview appeared to have fixed the problem with the received video. These are the steps I followed:

  1. I launched Skype and started a video call. The received video image had a grid of thin red lines and purple/green/blue tinting (similar to Snapshot 2).
  2. I Installed guvcview using the package manager.
  3. I launched guvcview in a Konsole (terminal) window. After guvcview created the file /home/fitzcarraldo/.config/guvcview/video0 and checked various video and audio settings it exited because my Webcam was being used by Skype (‘libv4l2: error setting pixformat: Device or resource busy‘).
  4. I clicked on the Webcam icon in the Skype call window, to turn my Webcam off.
  5. I launched guvcview again. The lower half of the received video image in Skype changed from a grid of thin red lines to a continuous green-coloured band, and the upper half of the image now looked reasonable but still had some red- or blue-tinged areas (see Snapshot 3 below).
  6. Snapshot 3 - Extract of received video image in Skype after I launched guvcview again

    Snapshot 3 - Extract of received video image in Skype after I launched guvcview again

  7. On the ‘Image Controls’ tab in the ‘GUVCViewer Controls’ window I changed the video frequency from 60 Hz to 50 Hz then back to 60 Hz again. I was just tinkering, and I believe this had no bearing on the outcome.
  8. I clicked on the ‘Quit’ button in the guvcview window to terminate the application.
  9. I clicked on the Webcam icon in the Skype call window to turn on again the Webcam, and the received Skype video image changed to a perfect image (see Snapshot 4 below).
  10. Snapshot 4 - Extract of received video image in Skype after I turned on again my Webcam in Skype

    Snapshot 4 - Extract of received video image in Skype after I turned on again my Webcam in Skype

It appears that guvcview had an effect on the received video image in Skype, although, if it did, I do not understand how. To check if the fix was permanent I ended the Skype video call, signed out of Skype and quit the application, rebooted and made a new Skype video call. The received video image in Skype was again perfect. I even deleted the guvcview configuration file and repeated this check, just in case the configuration file was somehow being used even though I had not launched guvcview, but the received video in yet another Skype video call was still perfect. I also clicked on the Webcam icon in the Skype call window several times during each call in order to turn my Webcam off and on several times; the received video image of the other person remained perfect.

So there you have it: when using an AMD ATI GPU and the Catalyst driver, it seems that guvcview can be used — at least in my case — to eliminate the type of image corruption in received Skype video shown in Snapshots 1 and 2. So, if you are also using the AMD Catalyst for Linux driver and are experiencing a similar problem, try guvcview. It might just do the trick.

‘Server not found’ by browser at launch

I haven’t had any significant Linux problems or new requirements in the last few months, hence no new posts here. My last real problem was back in June 2013 when I rolled my Gentoo installation to latest using Portage and found that, whenever I launched Firefox, it displayed the ‘Server not found’ page and I had to click ‘Try Again’, and then Firefox displayed the expected Web site. From then onwards, Firefox would work as expected until I exited the application. Thunderbird was also unable to access e-mail servers on the first attempt after it was launched. The same thing happened in Sabayon Linux when I rolled to latest using Entropy a couple of days later. Anyway, here is how I fixed the problem in both distributions.

First I used Wireshark to see what was going on, and it transpired that Gentoo (and Sabayon) was sending an IPv4 request followed quickly by an IPv6 request, but the reply to the IPv6 request was being received first and was a ‘server not found’ message since my ISP does not support IPv6 and my router apparently does not handle IPv6 requests correctly. Gentoo (and Sabayon) then used an IPv4 address when I clicked ‘Try Again’ in the browser window, and thereafter Firefox always dispayed the expected Web sites.

I should point out that IPv6 is enabled in the kernels I use and I’ve never before had to disable IPv6 in Firefox (or system-wide) on the affected laptops. So why the change in functionality, I wonder?

With Wireshark capturing packets, when I launched Firefox I was seeing a server failure message indicating “AAAA” (IPv6) instead of “A” (IPv4). To stop this happening I could have chosen any one of the three following solutions:

1. I could have used about:config in Firefox (and Config Editor in Thunderbird) to change the value of network.dns.disableIPv6 to true instead of false.

2. I could have disabled IPv6 system-wide by editing /etc/modprobe.d/aliases.conf and uncommenting the line “alias net-pf-10 off“.

3. I could have forced the getaddrinfo() function in glibc to make the IPv4 and IPv6 requests sequentially rather than in parallel.

Just for the fun of it I chose the third option on a couple of my laptops, and, as they use NetworkManager, this is how I did it:

fitzcarraldo@aspire5536 ~ $ su
Password:
aspire5536 fitzcarraldo # cat /etc/resolv.conf
# Generated by resolvconf
domain home
nameserver 192.168.1.254
aspire5536 fitzcarraldo # cd /etc/NetworkManager/dispatcher.d/
aspire5536 dispatcher.d # touch 06-dhclientoptions
aspire5536 dispatcher.d # nano 06-dhclientoptions
aspire5536 dispatcher.d # cat 06-dhclientoptions
#!/bin/bash
echo "options single-request" >> /etc/resolv.conf
aspire5536 dispatcher.d # chmod +x /etc/NetworkManager/dispatcher.d/06-dhclientoptions
aspire5536 dispatcher.d # # Now I disconnect then reconnect to the network
aspire5536 dispatcher.d # cat /etc/resolv.conf
# Generated by resolvconf
domain home
nameserver 192.168.1.254
options single-request
aspire5536 dispatcher.d #

As you can see above, I added a two-line Bash script 06-dhclientoptions in the directory /etc/NetworkManager/dispatcher.d/ that appends the line “options single-request” (without the quotes) to the contents of the file /etc/resolv.conf. The addition of the line “options single-request” in resolve.conf causes the getaddrinfo() function in glibc to make the IPv4 and IPv6 requests sequentially rather than in parallel. With this change, Firefox and Thunderbird no longer have a problem accessing the Internet the first time they are launched.

From “man 5 resolv.conf” under “options”:

single-request (since glibc 2.10)
sets RES_SNGLKUP in _res.options. By default, glibc performs IPv4 and IPv6 lookups in parallel since version 2.9. Some appliance DNS servers cannot handle these queries properly and make the requests time out. This option disables the behavior and makes glibc perform the IPv6 and IPv4 requests sequentially (at the cost of some slowdown of the resolving process).

single-request-reopen (since glibc 2.9)
The resolver uses the same socket for the A and AAAA requests. Some hardware mistakenly sends back only one reply. When that happens the client system will sit and wait for the second reply. Turning this option on changes this behavior so that if two requests from the same port are not handled correctly it will close the socket and open a new one before sending the second request.

I had to use NetworkManagerDispatcher to add the line “options single-request” to /etc/resolv.conf because NetworkManager overwrites /etc/resolv.conf if you edit it manually.

UPDATE (February 4, 2014): As I have recently seen the line “options single-request” occurring more than once in the file /etc/resolv.conf I now recommend /etc/NetworkManager/dispatcher.d/06-dhclientoptions consists of the following:

#!/bin/bash
if grep -q "options single-request" /etc/resolv.conf; then
    exit
else
    echo "options single-request" >> /etc/resolv.conf
fi

Dropbox revisited

In a previous post I explained how I installed Kfilebox, an unofficial KDE front-end for Dropbox. However, development of Kfilebox appears to have stopped, as the original author posted the following recently on a blog:

“I have stopped working on kfilebox after some updates in dropbox. Shortly: there is no way to get recent changed files, no more access to config options, cant configure it.”

Nevertheless I continued using Kfilebox. However, after a few days the Kfilebox icon stopped appearing in the KDE System Tray, and clicking on ‘Show hidden icons’ > ‘Kfilebox’ on the Panel displayed “The Dropbox daemon isn’t running” in the pop-up menu. Also, if I clicked on the hidden Kfilebox icon and selected ‘Preferences…’ the Dropbox folder field was empty and I had to keep re-entering the location of the Dropbox folder. So I decided to uninstall Kfilebox and try using Dropbox directly with KDE. I performed the steps listed below.

  1. Uninstall Kfilebox:

    # emerge -C kfilebox

  2. Remove any associated directories and files that might be left over:

    # rm -rf /home/fitzcarraldo/.dropbox
    # rm -rf /home/fitzcarraldo/.dropbox-dist
    # rm /home/fitzcarraldo/.kde4/share/config/kfileboxrc

  3. Install Dropbox:

    # emerge dropbox

  4. Do not edit /etc/conf.d/dropbox and do not configure Gentoo to launch the Dropbox daemon at start-up (i.e. do not add /etc/init.d/dropbox to the default runlevel). Instead configure KDE to launch the daemon when logging-in to KDE:
    1. Kickoff > System Settings > Startup and Shutdown
    2. Click on ‘Autostart’ in the left pane.
    3. Click on the ‘Add Script…’ button on the right side of the window.
    4. Enter the location of the Dropbox daemon in the box in the pop-up window. I entered “/opt/dropbox/dropboxd” (without the quotes) in the box and clicked ‘OK’.
  5. Run Dropbox for the first time and configure the local installation:
    1. Open a Dolphin window and browse to the directory containing the daemon (/opt/dropbox/) and double-click on dropboxd to launch the daemon.
    2. The Dropbox set-up window will pop-up and it should be obvious what to do from there onwards. As I already had a Dropbox account I selected ‘I already have a Dropbox account’ and clicked ‘Next’, I then entered my e-mail address, my Dropbox password and my computer’s name in the boxes and clicked ‘Next’. I left the default free 2 GB option selected and clicked ‘Next’. I left the default set-up ‘Typical’ selected and clicked ‘Install’. I read the introductory information displayed in the next couple of windows and clicked ‘Next’. I clicked ‘Finish’ in the final ‘That’s it!’ window.
  6. A Dropbox icon then appears in the System Tray on the Panel and synchronises with the Dropbox directory on the remote Dropbox server.

Now if I click on the Dropbox icon in the System Tray, the Dropbox directory window pops up. If I right-click on the icon in the System Tray, a menu pops-up with the expected Dropbox options.

So there was no need to use Kfilebox after all, as using the Dropbox daemon directly is just as user-friendly.

Installing Dropbox in Gentoo running KDE

kfilebox
I had never used Dropbox before and had no intention of doing so, but today a work colleague sent me some large files via Dropbox so I was forced to sign up. I tried to install Dropbox on my main laptop running Gentoo Linux and KDE but, for a well-known application, I had a surprising amount of trouble, hence this blog post.

To begin with, I found the following Dropbox-related packages:

# eix dropbox
* gnome-extra/nautilus-dropbox
Available versions: (~)0.6.9 (~)0.7.0 0.7.1 (~)1.4.0 {debug}
Homepage: http://www.dropbox.com/
Description: Store, Sync and Share Files Online
.
* net-misc/dropbox
Available versions: 1.2.48-r1^ms (~)1.2.51-r2^ms (~)1.4.3-r1^ms (~)1.4.7-r1^ms (~)1.4.7-r2^ms (~)1.4.17^ms (~)1.4.23^ms (~)1.6.16^ms {X +librsync-bundled}
Homepage: http://dropbox.com/
Description: Dropbox daemon (pretends to be GUI-less)
.
* net-misc/dropbox-cli
Available versions: 1 1-r1 {PYTHON_TARGETS="python2_6 python2_7"}
Homepage: http://www.dropbox.com/
Description: Cli interface for dropbox daemon (python)
.
* xfce-extra/thunar-dropbox [1]
Available versions: [m](~)0.2.0
Homepage: http://www.softwarebakery.com/maato/thunar-dropbox.html
Description: Plugin for Thunar that adds context-menu items for Dropbox
.
[1] "sabayon" /var/lib/layman/sabayon
.
Found 4 matches.

But I don’t have GNOME or Xfce installed on my main laptop, so the first and last packages were of no interest. A quick search on the Web turned up Kfilebox, which seemed to be exactly what I needed. I was pleased to find that the package is in the main Portage tree:

# eix kfilebox
* kde-misc/kfilebox
Available versions: (4) (~)0.4.8 (~)0.4.9
{LINGUAS="ar br cs de el es fr gl it lt nl pl pt ru si tr zh zh_CN"}
Homepage: http://kdropbox.deuteros.es/
Description: KDE dropbox client

So I installed kfilebox, dropbox and dropbox-cli, thinking I would need them all. Then, before doing anything else, I surfed to the Dropbox Web site and signed up for an account.

I launched Konsole and entered the command kfilebox. A window popped-up telling me that the Dropbox Daemon was being downloaded, then another window popped up offering me two options/buttons: ‘Run gtk based installer’ and ‘Or simply link account’. I clicked on the latter, thinking that was all I needed to do as I had already signed up for an account via the Dropbox Web site. But a Dropbox icon did not appear in the Panel, nor did Dolphin show a Dropbox folder icon in my home directory, and the KDE Notifications widget kept popping up notification after notification from Kfilebox to “Please visit url to link to this machine”. The trouble was that clicking on the apparent link in the notifications did nothing.

The directories .dropbox and .dropbox-dist existed in my home directory, and the contents of /home/fitzcarraldo/.kde4/share/config/kfileboxrc were as follows:

[General]
AutoStart=true
Browser=rekonq
DropboxDir=/home/fitzcarraldo/.dropbox-dist/
FileManager=dolphin
GtkUiDisabled=true
IconSet=default
ShowNotifications=true
StartDaemon=true

As the rekonq Web browser is not installed on this laptop, I edited the file and changed Browser=rekonq to Browser=firefox then rebooted, but it made no difference.

So I uninstalled everything:

# emerge -C kfilebox dropbox dropbox-cli
# rm -rf /home/fitzcarraldo/.dropbox
# rm -rf /home/fitzcarraldo/.dropbox-dist
# rm /home/fitzcarraldo/.kde4/share/config/kfileboxrc

then rebooted and reinstalled only Kfilebox:

# emerge kfilebox

I then launched Konsole and entered the command kfilebox. The pop-up window appeared notifying me that the Dropbox Daemon was being downloaded, followed by the pop-up window offering me the choice of running the gtk-based installer or simply linking the account. This time I chose the option to run the gtk-based installer and just followed the intuitive instructions in the various pop-up windows that followed, one of which offered to create a new Dropbox account or to link to an existing Dropbox account. As I wanted to do the latter I entered my e-mail address and Dropbox password, a Dropbox icon then appeared on the Panel and a Dropbox folder icon is now visible in Dolphin.

I checked the contents of ~/.kde4/share/config/kfileboxrc and they were the same as listed above, so I edited the file to replace rekonq with firefox, although I’m not sure yet what (if anything) that does, as Dropbox is new to me and I’m still learning. Anyway, the important thing is that I could now click on the ‘View folder’ button in an e-mail sent to me by a colleague and the files uploaded by my colleague were automatically downloaded into the ~/Dropbox directory.

EDIT May 30, 2013: Kfilebox is no longer in development and has started playing up. However, I found out how to install Dropbox directly and use it with KDE, and it’s just as user-friendly as Kfilebox. See my post Dropbox revisited for how to install Dropbox directly.

Switching the display quickly between a laptop monitor and an external monitor or projector in Linux

laptop_with_external_monitor_and_keyboardI connect my laptop to an external keyboard and an external monitor or projector in various offices and at home, and each of the monitors has a different resolution. Fn-F3 on my laptop keyboard allows me to toggle between monitors, but I want more control (including the ability to specify the resolution of the external display). Now, I find the GPU manufacturer’s application and the Desktop Environment’s GUI for switching monitors and changing screen resolution rather cumbersome, so I wanted an icon on the Desktop that I could double-click to switch monitors without having to enter the root user’s password and fiddle around too much. So I decided to create some simple Bash scripts and associated Desktop Config files with nice-looking icons on the desktop, which I can launch easily and quickly by double-clicking. Obviously the resolutions are limited to the range of resolutions supported by the GPU and external monitor.

The suite of Desktop Config files I created have self-explanatory names:

$ cd ~/Desktop
$ ls -1 Switch*
Switch_OFF_laptop_monitor_if_external_monitor_is_connected
Switch_OFF_laptop_monitor_if_external_monitor_is_connected_auto
Switch_ON_laptop_monitor_and_external_monitor
Switch_ON_laptop_monitor_and_switch_off_external_monitor
$ ls -1 Toggle*
Toggle_display

The difference between Switch_OFF_laptop_monitor_if_external_monitor_is_connected and Switch_OFF_laptop_monitor_if_external_monitor_is_connected_auto is that the former prompts for the resolution of the external monitor whereas the latter tries to find the resolution automatically. I have both because I have found that, for some external display devices (e.g. projectors), it is handy to have the ability to specify the resolution manually.

Switch off the laptop monitor if an external monitor is connected (find resolution automatically)

The Desktop Config file I double-click the most is ~/Desktop/Switch_OFF_laptop_monitor_if_external_monitor_is_connected_auto, and it contains the following text:

[Desktop Entry]
Comment[en_GB]=switch off laptop monitor if external monitor is connected auto
Comment=switch off laptop monitor if external monitor is connected auto
Exec=sh /home/fitzcarraldo/switch_off_laptop_monitor_if_external_monitor_is_connected_auto.sh
GenericName[en_GB]=Switch off laptop monitor if external monitor is connected auto
GenericName=Switch off laptop monitor if external monitor is connected auto
Icon=/home/fitzcarraldo/Pictures/Icons/display.png
MimeType=
Name[en_GB]=Switch_OFF_laptop_monitor_if_external_monitor_is_connected_auto
Name=Switch_OFF_laptop_monitor_if_external_monitor_is_connected_auto
Path=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=none
X-KDE-SubstituteUID=false
X-KDE-Username=

The Bash script it launches, ~/switch_off_laptop_monitor_if_external_monitor_is_connected_auto.sh, contains the following code:

#!/bin/bash
if xrandr -q | grep "CRT1 connected"; then
  xrandr --output LVDS --off
  xrandr --output CRT1 --off
  xrandr --output CRT1 --auto
else
  xrandr --output CRT1 --off
  xrandr --output LVDS --off
  xrandr --output LVDS --mode 1920x1080
# 1920x1080 is the native resolution of my laptop monitor
fi

Don’t forget to make them executable:

$ chmod +x /home/fitzcarraldo/Desktop/Switch_OFF_laptop_monitor_if_external_monitor_is_connected_auto
$ chmod +x /home/fitzcarraldo/switch_off_laptop_monitor_if_external_monitor_is_connected_auto.sh

If you’re wondering how I knew I had to specify ‘CRT1′ and ‘LVDS’ in the Bash script, I used the xrandr command to find out what names the GPU gives the monitors:

$ xrandr
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 1920 x 1920
LVDS connected (normal left inverted right x axis y axis)
1920x1080 60.0 +
1680x1050 60.0
1400x1050 60.0
1600x900 60.0
1280x1024 60.0
1440x900 60.0
1280x960 60.0
1280x768 60.0
1280x720 60.0
1024x768 60.0
1024x600 60.0
800x600 60.0
800x480 60.0
640x480 60.0
DFP1 disconnected (normal left inverted right x axis y axis)
CRT1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 476mm x 268mm
1920x1080 60.0*+
1280x1024 75.0 60.0
1280x960 60.0
1280x800 59.8
1152x864 75.0
1280x720 60.0
1024x768 75.0 70.1 60.0
800x600 72.2 75.0 60.3 56.2
640x480 75.0 72.8 67.0 59.9

Switch off the laptop monitor if an external monitor is connected (enter resolution)

The Desktop Config file I double-click is ~/Desktop/Switch_OFF_laptop_monitor_if_external_monitor_is_connected, and it contains the following text:

[Desktop Entry]
Comment[en_GB]=switch off laptop monitor if external monitor is connected
Comment=switch off laptop monitor if external monitor is connected
Exec=sh /home/fitzcarraldo/System_Administration/switch_off_laptop_monitor_if_external_monitor_is_connected.sh
GenericName[en_GB]=Switch off laptop monitor if external monitor is connected
GenericName=Switch off laptop monitor if external monitor is connected
Icon=/home/fitzcarraldo/Pictures/Icons/display.png
MimeType=
Name[en_GB]=Switch_OFF_laptop_monitor_if_external_monitor_is_connected
Name=Switch_OFF_laptop_monitor_if_external_monitor_is_connected
Path=
StartupNotify=true
Terminal=true
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=none
X-KDE-SubstituteUID=false
X-KDE-Username=

The Bash script it launches, ~/switch_off_laptop_monitor_if_external_monitor_is_connected.sh, contains the following code:

#!/bin/bash
if xrandr -q | grep "CRT1 connected"; then
echo -n "Enter resolution width of external monitor (hint 1920 Doha, 1440 home): "
read EXTERNAL_WIDTH
echo -n "Enter resoluton height of external monitor (hint 1080 Doha, 900 home): "
read EXTERNAL_HEIGHT
  xrandr --output LVDS --off
  xrandr --output CRT1 --off
  xrandr --output CRT1 --mode $EXTERNAL_WIDTH"x"$EXTERNAL_HEIGHT
else
  xrandr --output CRT1 --off
  xrandr --output LVDS --off
  xrandr --output LVDS --mode 1920x1080
# 1920x1080 is the native resolution of my laptop monitor
fi

Don’t forget to make them executable:

$ chmod +x /home/fitzcarraldo/Desktop/Switch_OFF_laptop_monitor_if_external_monitor_is_connected
$ chmod +x /home/fitzcarraldo/switch_off_laptop_monitor_if_external_monitor_is_connected.sh

Switch on the laptop monitor and external monitor simultaneously

I don’t need to use this one much, only when I am using an external monitor but suddenly want to use the laptop’s built-in Webcam and so have to open fully the laptop’s lid. The file ~/Desktop/Switch_ON_laptop_monitor_and_external_monitor contains the following text:

[Desktop Entry]
Comment[en_GB]=switch_ON_laptop_monitor_and_external_monitor
Comment=switch_ON_laptop_monitor_and_external_monitor
Exec=sh /home/fitzcarraldo/switch_on_laptop_monitor_and_external_monitor.sh
GenericName[en_GB]=Switch_ON_laptop_monitor_and_external_monitor
GenericName=Switch_ON_laptop_monitor_and_external_monitor
Icon=/home/fitzcarraldo/Pictures/Icons/display.png
MimeType=
Name[en_GB]=Switch_ON_laptop_monitor_and_external_monitor
Name=Switch_ON_laptop_monitor_and_external_monitor
Path=
StartupNotify=true
Terminal=true
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=none
X-KDE-SubstituteUID=false
X-KDE-Username=

and the Bash script it calls, ~/switch_on_laptop_monitor_and_external_monitor.sh, contains the following code:

#!/bin/bash
if xrandr -q | grep "CRT1 connected"; then
  echo "Note that the resolution specified must be the same for both monitors, and must be achievable on both monitors."
  echo -n "Enter resolution width of external monitor (hint 1920 office, 1440 home): "
  read EXTERNAL_WIDTH
  echo -n "Enter resoluton height of external monitor (hint 1080 office, 900 home): "
  read EXTERNAL_HEIGHT
  #xrandr --output LVDS --off
  xrandr --output LVDS --mode $EXTERNAL_WIDTH"x"$EXTERNAL_HEIGHT
  xrandr --output CRT1 --off
  xrandr --output CRT1 --mode $EXTERNAL_WIDTH"x"$EXTERNAL_HEIGHT
else
  xrandr --output CRT1 --off
  xrandr --output LVDS --off
  xrandr --output LVDS --mode 1920x1080
# 1920x1080 is the native resolution of my laptop monitor
fi

Don’t forget to make them executable:

$ chmod +x /home/fitzcarraldo/Desktop/Switch_ON_laptop_monitor_and_external_monitor
$ chmod +x /home/fitzcarraldo/switch_on_laptop_monitor_and_external_monitor.sh

Switch on the laptop monitor and switch off an external monitor

I don’t need to use this one much either, given that the display mode reverts to the laptop monitor after I reboot or shutdown/power-up the laptop. The file ~/Desktop/Switch_ON_laptop_monitor_and_external_monitor contains the following text:

[Desktop Entry]
Comment[en_GB]=switch on laptop monitor and switch off external monitor
Comment=switch on laptop monitor and switch off external monitor
Exec=sh /home/fitzcarraldo/switch_on_laptop_monitor_and_switch_off_external_monitor.sh
GenericName[en_GB]=Switch on laptop monitor and switch off external monitor
GenericName=Switch on laptop monitor and switch off external monitor
Icon=computer-laptop
MimeType=
Name[en_GB]=Switch_ON_laptop_monitor_and_switch_off_external_monitor
Name=Switch_ON_laptop_monitor_and_switch_off_external_monitor
Path=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=
X-KDE-SubstituteUID=false
X-KDE-Username=

The Bash script it launches, ~/switch_on_laptop_monitor_and_switch_off_external_monitor.sh, contains the following code:

#!/bin/bash
xrandr --output CRT1 --off
xrandr --output LVDS --auto
xrandr --output LVDS --mode 1920x1080
# 1920x1080 is the native resolution of my laptop monitor

I did also create a fifth Desktop Config file and associated Bash script, to toggle between the three modes (laptop monitor only > both monitors > external monitor only) rather than having to double-click three different icons. But, to be honest, it’s quicker and easier to have the three icons and double-click on the one I want rather than toggling through three display modes. Anyway, in case you are interested, the Desktop Config file ~/Desktop/Toggle_Display contains the follow text:

[Desktop Entry]
Comment[en_GB]=Toggle between laptop monitor, external monitor and both
Comment=Toggle between laptop monitor, external monitor and both
Exec=sh /home/fitzcarraldo/toggle_display.sh
GenericName[en_GB]=Toggle between laptop monitor, external monitor and both
GenericName=Toggle between laptop monitor, external monitor and both
Icon=video-display
MimeType=
Name[en_GB]=Toggle_display
Name=Toggle_display
Path=
StartupNotify=false
Terminal=false
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=none
X-KDE-SubstituteUID=false
X-KDE-Username=

and the Bash script it launches, ~/switch_on_laptop_monitor_and_external_monitor.sh, contains the following code:

#!/bin/sh

# Using the xrandr command I found that the two video outputs from my laptop are named LVDS
# (the internal display) and CRT1 (the external display driven by the laptop's VGA socket).
# My external monitor at home has a resolution of 1440x900.

CONNECTED=`xrandr | grep -i ' connected' | grep LVDS | awk '{print $1}'`
CONNECTED="${CONNECTED} `xrandr | grep -i ' connected' | grep CRT | awk '{print $1}'`"

ENABLED=`awk '{print;exit}' ~/displays_enabled 2>/dev/null`

if [ "$CONNECTED" = "LVDS" -o "$CONNECTED" = "LVDS " -o "$CONNECTED" = " LVDS" ]; then
        # Only the internal display is connected, so don't do anything.
        echo "LVDS" > ~/displays_enabled
        ENABLED="LVDS"
        xrandr --output CRT1 --off
        xrandr --output LVDS --off
        xrandr --output LVDS --auto
        exit 0
elif [ "$CONNECTED" = "LVDS CRT1" ]; then
        # Both the internal and external displays are connected, so let's toggle
        # LVDS > LVDS,CRT1 > CRT1

        EXTERNALRES=`xrandr | awk 'c&&c--;/ connected/{c=1}' | awk '{print $1}' | grep 1440x900`
        if [ "$ENABLED" = "LVDS" ]; then
        # Switching on both displays.
                xrandr --output LVDS --off
                if [ "$EXTERNALRES" = "1440x900" ]; then
                         xrandr --output LVDS --mode 1440x900
                         xrandr --output CRT1 --off
                         xrandr --output CRT1 --auto
                else
                         xrandr --output LVDS --auto
                         xrandr --output CRT1 --off
                         xrandr --output CRT1 --auto
                fi
                ENABLED="LVDS CRT1"
                echo "LVDS CRT1" > ~/displays_enabled
        elif [ "$ENABLED" = "LVDS CRT1" ]; then
        # Switching on only external display.
                xrandr --output LVDS --off
                xrandr --output CRT1 --off
                xrandr --output CRT1 --auto
                ENABLED="CRT1"
                echo "CRT1" > ~/displays_enabled
        else
        # Switching on only internal display.
                xrandr --output CRT1 --off
                xrandr --output LVDS --off
                xrandr --output LVDS --auto
                ENABLED="LVDS"
                echo "LVDS" > ~/displays_enabled
        fi
fi

As I use KDE, I also used System Settings > Shortcuts and Gestures | Custom Shortcuts to create a keyboard shortcut which I named ‘Toggle display’, with Meta+P as Trigger and sh ~/toggle_display.sh as Action, but I tend to use the mouse rather than the keyboard in any case.

By the way, you might think some of the xrandr commands in the above Bash scripts are redundant. You would be correct in thinking that, but in practice I found that the displays did not switch if I didn’t include the additional commands shown (due to a bug in xrandr, perhaps?). Even then, when I switch to an external monitor, occasionally the screen resolution is slightly too big or too small, so I placed the icons at the top left of the desktop so that they are always accessible and I can just double-click on the same icon again if necessary. As I’m using KDE, I placed a Folder View Plasmoid for ~/Desktop/ at the top left of the desktop, as you can see in the screenshot.

Desktop showing icons for switching between monitors

Footnote

I’ve been using the above method of switching between displays for a couple of years now with an AMD ATI GPU. It works nicely and suits my needs perfectly. AMD has supported xrandr since 2008 (see Ref. 1), whereas NVIDIA only began to support xrandr last year (see Ref. 2) so I’m not sure how well these scripts would work with NVIDIA GPUs.

Ref. 1: AMD Catalyst 8.9 Gets WINE Fix, RandR 1.2 Support, September 18, 2008
Ref. 2: NVIDIA’s 302 Linux Driver Finally Has RandR 1.2/1.3, May 2, 2012

How to prevent a USB mouse auto-suspending in Linux when a laptop’s power supply is disconnected

I found that my USB mouse (and external USB keyboard) went to sleep when the mains power supply was disconnected from my laptop. This was annoying because I had to click a mouse button and wait a couple of seconds in order to wake up the mouse. You can see from the console output below that several USB devices were being auto-suspended when I unplugged the laptop PSU:

# # PSU is currently connected.
# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 on 1.5 USB Laser Mouse
1-1.3 on 12 BCM2046 Bluetooth Device
2-1.2 on 12 Fingerprint Sensor
2-1.3 on 480 USB 2.0 Camera
2-1.6 on 1.5 USB Keyboard
# # Now I will disconnect the PSU...
# # PSU is currently disconnected.
# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 auto 1.5 USB Laser Mouse
1-1.3 auto 12 BCM2046 Bluetooth Device
2-1.2 auto 12 Fingerprint Sensor
2-1.3 auto 480 USB 2.0 Camera
2-1.6 auto 1.5 USB Keyboard
#

I found out the Vendor ID (046d) and Product ID (c052) of my Logitech NX50 USB portable/travel mouse by unplugging then reconnecting the USB mouse and using the dmesg command:

[13628.909728] usb 1-1.2: USB disconnect, device number 5
[13634.454132] usb 1-1.2: new low-speed USB device number 6 using ehci_hcd
[13634.535107] usb 1-1.2: New USB device found, idVendor=046d, idProduct=c052
[13634.535111] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[13634.535113] usb 1-1.2: Product: USB Laser Mouse
[13634.535115] usb 1-1.2: Manufacturer: Logitech
[13634.540168] input: Logitech USB Laser Mouse as /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/input/input17
[13634.540582] hid-generic 0003:046D:C052.0005: input,hidraw0: USB HID v1.10 Mouse [Logitech USB Laser Mouse] on usb-0000:00:1a.0-1.2/input0

First I tried creating a local Udev rule:

# cat /etc/udev/rules.d/91-local.rules
ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="USB Laser Mouse", ATTR{power/control}="on"

That didn’t stop the mouse from auto-suspending (and neither did “Logitech USB Laser Mouse” instead of “USB Laser Mouse”), so I tried creating a Udev rule specifying the Vendor ID and Product ID of the mouse:

# cat /etc/udev/rules.d/91-local.rules
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTR{idProduct}=="c052", TEST=="power/control", ATTR{power/control}="on"

That didn’t stop the mouse from auto-suspending either.

Then I remembered that laptop-mode-tools is installed on my laptop:

# eix laptop-mode-tools
[I] app-laptop/laptop-mode-tools
Available versions: 1.60-r1 (~)1.62-r1 {(+)acpi apm bluetooth scsi}
Installed versions: 1.62-r1(18:10:15 11/01/13)(acpi bluetooth -apm -scsi)
Homepage: http://www.samwel.tk/laptop_mode/
Description: Linux kernel laptop_mode user-space utilities

So then I tried adding the mouse model to the blacklist in /etc/laptop-mode/conf.d/usb-autosuspend.conf by making AUTOSUSPEND_USBID_BLACKLIST="046d:c052" as shown below:

#
# Configuration file for Laptop Mode Tools module usb-autosuspend.
#
# For more information, consult the laptop-mode.conf(8) manual page.
#


###############################################################################
# USB autosuspend settings
# ------------------------
#
# If you enable this setting, laptop mode tools will automatically enable the
# USB autosuspend feature for all devices.
#
# NOTE: Some USB devices claim they support autosuspend, but implement it in a
# broken way. This can mean keyboards losing keypresses, or optical mice turning
# their LED completely off. If you have a device that misbehaves, add its USB ID
# to the blacklist below and complain to your hardware vendor.
################################################################################

# Enable debug mode for this module
# Set to 1 if you want to debug this module
DEBUG=0

# Enable USB autosuspend feature?
# Set to 0 to disable
CONTROL_USB_AUTOSUSPEND="auto"

# Set this to use opt-in/whitelist instead of opt-out/blacklist for deciding
# which USB devices should be autosuspended.
# AUTOSUSPEND_USE_WHITELIST=0 means AUTOSUSPEND_*_BLACKLIST will be used.
# AUTOSUSPEND_USE_WHITELIST=1 means AUTOSUSPEND_*_WHITELIST will be used.
AUTOSUSPEND_USE_WHITELIST=0

# The list of USB IDs that should not use autosuspend. Use lsusb to find out the
# IDs of your USB devices.
# Example: AUTOSUSPEND_USBID_BLACKLIST="046d:c025 0123:abcd"
AUTOSUSPEND_USBID_BLACKLIST="046d:c052"

# The list of USB driver types that should not use autosuspend.  The driver
# type is given by "DRIVER=..." in a USB device's uevent file.
# Example: AUTOSUSPEND_USBID_BLACKLIST="usbhid usb-storage"
AUTOSUSPEND_USBTYPE_BLACKLIST=""

# The list of USB IDs that should use autosuspend. Use lsusb to find out the
# IDs of your USB devices.
# Example: AUTOSUSPEND_USBID_WHITELIST="046d:c025 0123:abcd"
AUTOSUSPEND_USBID_WHITELIST=""

# The list of USB driver types that should use autosuspend.  The driver
# type is given by "DRIVER=..." in a USB device's uevent file.
# Example: AUTOSUSPEND_USBTYPE_WHITELIST="usbhid usb-storage"
AUTOSUSPEND_USBTYPE_WHITELIST=""

# Trigger auto-suspension of the USB deivce under conditional circumstances
BATT_SUSPEND_USB=1
LM_AC_SUSPEND_USB=0
NOLM_AC_SUSPEND_USB=0

# USB Auto-Suspend timeout in seconds
# Number of seconds after which the USB devices should suspend
AUTOSUSPEND_TIMEOUT=2

And now the mouse no longer suspends when I unplug the PSU:

# # PSU is currently connected.
# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 on 1.5 USB Laser Mouse
1-1.3 on 12 BCM2046 Bluetooth Device
2-1.2 on 12 Fingerprint Sensor
2-1.3 on 480 USB 2.0 Camera
2-1.6 on 1.5 USB Keyboard
# # Now I will disconnect the PSU...
# # PSU is currently disconnected.
# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 on 1.5 USB Laser Mouse
1-1.3 auto 12 BCM2046 Bluetooth Device
2-1.2 auto 12 Fingerprint Sensor
2-1.3 auto 480 USB 2.0 Camera
2-1.6 auto 1.5 USB Keyboard
# # Now I will reconnect the PSU...
# # PSU is currently connected.
# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 on 1.5 USB Laser Mouse
1-1.3 on 12 BCM2046 Bluetooth Device
2-1.2 on 12 Fingerprint Sensor
2-1.3 on 480 USB 2.0 Camera
2-1.6 on 1.5 USB Keyboard
#

So configuring laptop-mode-tools solved the problem with the mouse. Mind you, I will probably simply make CONTROL_USB_AUTOSUSPEND="no" in /etc/laptop-mode/conf.d/usb-autosuspend.conf, as I don’t want the internal USB devices in my laptop (Bluetooth adapter, fingerprint sensor and Webcam) to auto-suspend either.

Follow

Get every new post delivered to your Inbox.

Join 43 other followers