Journal Articles
Browse in : |
All
> Journals
> CVu
> 321
(11)
All > Topics > Programming (877) Any of these categories - All of these categories |
Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.
Title: Making a Linux Desktop – Launching Applications
Author: Bob Schmidt
Date: 03 March 2020 23:03:18 +00:00 or Tue, 03 March 2020 23:03:18 +00:00
Summary: Alan Griffiths continues his series on the Mir desktop.
Body:
I’m working on a project (Mir [1]) that, among other things, aims to make it easy to develop graphical ‘desktop environments’ for Linux. There’s a lot of features that are common between all designs for desktop environments and, in addition, a lot that is common between the majority of designs. For example, it is common for applications to draw ‘windows’ and for these to be combined onto the screen.
By providing the common features, and for the rest offering both sensible defaults and an easy way to customise them Mir is designed to support a range of possible designs.
Last issue we finished with a basic but functional desktop shell with some wallpaper. This time we’ll extend that with the capability to select and launch applications from the desktop.
Preparation
The code in this article needs Mir 1.2 (or later). On Ubuntu 18.04 (and later) Mir 1.7 is available from the mir-team/release PPA. To build it requires a few additional packages as indicated below. It is also useful to install the Qt toolkit’s Wayland support: qtwayland5. And finally, the g++ compiler and cmake.
$ sudo apt-add-repository ppa:mir-team/release $ sudo apt install libmiral-dev mir-graphics- drivers-desktop libwayland-dev $ sudo apt install libfreetype6-dev libxkbcommon- dev libboost-filesystem-dev $ sudo apt install qtwayland5 $ sudo apt install g++ cmake
Mir 1.6 is available on Fedora and can be built from source for many versions of Linux.
Building the example
The full code for this example is available on github [2]:
$ git clone https://github.com/AlanGriffiths/ egmde.git $ git checkout Article-3
Naturally, the code is likely to evolve, so you will find other branches, but the Article-3 branch goes with this article. Assuming that you’ve MirAL installed as described above you can now build egmde as follows:
$ mkdir egmde/build $ cd egmde/build $ cmake .. $ make
Running the example
After this you can start egmde:
$ ./egmde
This time the Mir-on-X window should have a coloured gradient with the words “Ctrl-Alt-A = app launcher | Ctrl-Alt-T = terminal | Ctrl-Alt-BkSp = quit†at the bottom.
If you press Ctrl-Alt-A you will see the name of one of the programs available on your computer, pressing up or down arrows will change the named program (as will pressing the initial letter of another program), pressing Space or Enter will (attempt to) launch the program.
If you have a touchscreen, you can activate the app launcher by swiping from the left edge, launch the shown app by touching the middle of the screen and change apps by touching the top or bottom area.
Normally launching the program will succeed, but if the program doesn’t run using Wayland then it will fail. (A future article will explore supporting X11-only applications.)
Listing ‘desktop’ applications
The ‘Desktop Entry Specification’ [3] details how desktops identify the available programs, the icons and text to display (in potentially many languages) and the command(s) to run them. Like GNOME, KDE, Unity and other desktop environments, egmde follows this specification.
This specification covers the places to look for .desktop files, and the content of these files. A large chunk of the new code deals with finding these files and extracting the name and command to execute.
The remaining code is based on the FullscreenClient
class we saw in the last article and deals with offering a selection from the applications found in the .desktop files.
The example code
I’ll leave the interested reader to find and read the code of the new Launcher
class, it deals with parsing files, handling the display and user input. I’ll just show the changes to the main file. Listing 1 shows the keyboard and touchscreen handling code to show the launcher.
ExternalClientLauncher external_client_launcher; egmde::Launcher launcher {external_client_launcher}; … switch (mir_keyboard_event_scan_code(kev)) { case KEY_A:launcher.show(); return true; … auto touch_shortcuts = [&, gesture = false](MirEvent const* event) mutable { if (mir_event_get_type(event) != mir_event_type_input) return false; auto const* input_event = mir_event_get_input_event(event); if (mir_input_event_get_type(input_event) != mir_input_event_type_touch) return false; auto const* tev = mir_input_event_get_touch_event(input_event); if (gesture) { if (mir_touch_event_action(tev, 0) == mir_touch_action_up) gesture = false; return true; } if (mir_touch_event_point_count(tev) != 1) return false; if (mir_touch_event_action(tev, 0) != mir_touch_action_down) return false; if (mir_touch_event_axis_value(tev, 0, mir_touch_axis_x) >= 5) return false; launcher.show(); gesture = true; return true; }; … runner.add_stop_callback([&] {launcher.stop();}); |
Listing 1 |
In the initial article of this series, the program simply expected to use weston-terminal as a Wayland based terminal emulator. This version actually tries to find a terminal that’s already installed. (There are two mechanisms for identifying a default terminal emulator on Linux: x-terminal-emulator from Debian and xdg-terminal from XDG. Sadly neither reflects user preferences, or Wayland support.) Listing 2 shows the new code.
namespace { // Neither xdg-terminal nor x-terminal-emulator // is guaranteed to exist, and neither is a good // way to identify user preference... std::string const terminal_cmd = []() -> std::string { auto const user_bin = "/usr/bin/"; for (std::string name : { "weston-terminal", "gnome-terminal", "konsole", "qterminal", "lxterminal", "xdg-terminal"}) { if (boost::filesystem::exists(user_bin + name)) return name; } return "x-terminal-emulator"; }(); } … external_client_launcher.launch( {"weston-terminal"}); case KEY_T: external_client_launcher.launch ({terminal_cmd}); return true; |
Listing 2 |
Conclusion
The program has grown from the 75 lines in the initial working example, but has started to look a little more polished and is a lot more functional. It is still not a big program (see below).
$ wc -l *.cpp *.h 616 egfullscreenclient.cpp 639 eglauncher.cpp 147 egmde.cpp 176 egwallpaper.cpp 46 egwindowmanager.cpp 53 egworker.cpp 201 printer.cpp 236 egfullscreenclient.h 53 eglauncher.h 58 egwallpaper.h 43 egwindowmanager.h 52 egworker.h 54 printer.h 2374 total
References
[1] The Mir homepage: https://mir-server.io/
[2] The egmde git repo: https://github.com/AlanGriffiths/egmde
[3] ‘Desktop Entry Specification’:https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
has delivered working software and development processes to a range of organizations, written for a number of magazines, spoken at several conferences, and made many friends.
Notes:
More fields may be available via dynamicdata ..