Design Failure: Removing the Minimize Button Elementary OS 5.0 Luna

Recently ElementaryOS 5.0 Juno got released. I immediately upgraded. Looked at it for two seconds and decided to go with Ubuntu.

The ‘killer’ feature that was missing was a small one – the minimize button is still not enabled by default.

Why was the minimize button removed?

Digging into this topic I found a statement about removing the default button.

a plan had already been laid out for the new standard of elementary apps: They would open and close instantly and even better, they would save their state before closing. 

Elementary Blog – Shaking up Window Controls (

Basically they decided that elementary apps should act as mobile apps. Thus combining the minimize function with the close button.

Elementary OS is a desktop OS and if it wants to be successful it allows you to use all programs and not only apps designed for elementary OS.

Is it a good design decision?

Removing the minimize button is a bold move. It radically changes how the user deals with window management.

The Pros

Instead of minimize you need to use tools like multiple desktops Users could start working more with multiple desktops.

The Cons

  1. The concept of a minimize has been around since even before 1988 – It has become one of the core components of Desktop OS and Window management. Every user will have to relearn their interaction.
  2. The communication of the user with the computer is awkward and creates misunderstandings. The apps will guess what you want to do: Did you want to listen to music and keep the program open in the background or did you want to stop listening for music? The user has only one button to express both of these commands.

Probably the button is actually not used that often anymore, since most things are done with a browser and that window is always open. – I do not know I do not have any data to back that claim.

However I know that that line of thinking lead to the removal of the start button in Windows 8 and that was definitely not a good idea.

Goodbye Elementary OS

While Elementary OS has a wonderful UI and they try to focus a lot more on usability. The missing of this button makes the OS unusable for me.

In Elementary OS 0.4 Freya – I enabled the button with the command:

gsettings set org.pantheon.desktop.gala.appearance button-layout 'close,minimize,maximize'

However that made the UI look a little weird and sometimes it just did not work. I just assumed that when a lot of people are googling for the problem and mentioning it – that eventually they will reconsider their choice. However currently it does not seem to be the case.

So back to Ubuntu – that UI also has flaws, but it got it right to have a minimize button.

Ubuntu 18.10: NVidia RTX Drivers

NVidias newly released RTX Graphics cards will not be automatically detected by Ubuntu. In order to get the cards running properly you need to install the NVidia drivers with the version 410 or newer.

In order to install the driver you must run following commands:

sudo add-apt-repository ppa:graphics-drivers
sudo apt update
sudo apt install nvidia-driver-410 
sudo reboot

Things to do after installing Elementary OS 0.4.1 (Loki)

When you start out with elementary OS there are a couple of useful things that you should do to have a better experience working with your system.


“Software & Updates” for Additional Drivers

The easiest way to install the proprietary NVidia Drivers (in Ubuntu) is to go to System Settings > Additional Drivers and then simply select the driver.

This option is not available in Elementary. However, by installing the package software-properties-gtk you can get the program.

sudo apt install -y software-properties-gtk

Now by clicking on Applications on the top right, and then type “Software & Updates” you can access the Settings.

Easy way to add PPA

With the command line tool add-apt-repository you have a quick way to add additional PPA’s. To get this tool you need to install the package

sudo apt-get install software-properties-common

MS Fonts

sudo apt-get install ttf-mscorefonts-installer

Add a Minimize Button to Windows

Some of the Elementary Windows do not have an easy way to minimize the window. With Elementary Tweaks, you can add a button to the windows.

Officially the elementary team does not encourage users to use the tweaking tool. It exposes switches to functionality that could mess up your system – use the tool with caution.

sudo add-apt-repository ppa:philip.scott/elementary-tweaks
sudo apt install elementary-tweaks

Chromium Browser

sudo apt install chromium-browser
sudo apt remove epiphany-browser -y

Screenshot Tool

sudo apt remove screenshot-tool
sudo add-apt-repository ppa:shutter/ppa
sudo apt-get update
sudo apt-get install -y shutter

Video Lan

sudo apt install -y vlc
sudo apt remove audience -y

Web Development Tools

Visual Studio Code

curl | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64] stable main" > /etc/apt/sources.list.d/vscode.list'
sudo apt update
sudo apt install code


sudo apt install git


curl -sL | sudo -E bash -
sudo apt-get install -y nodejs

System Update

sudo apt-get update
sudo apt-get dist-upgrade

Remove Programs

sudo apt remove pantheon-mail -y
sudo apt remove maya-calendar -y
sudo apt autoremove



sudo apt install libreoffice
sudo apt install gimp inkscape shutter


sudo apt-get install ubuntu-restricted-extras ffmpeg

Puppeteer.JS – Using Headless Chrome for Site Crawling

PuppeteerJS essentially allows you to automate Chrome. Headless Chrome allows you to run Chrome without actually rendering the webpage. Sounds silly, but has a lot of useful applications, you could for example simply write a test script that ensures that your website is still working correctly.


npm i puppeteer
# or
yarn add puppeteer


We are going to look at a quick example of how to Log In to a site and then do some operation.

Initialize Puppeteer

You need to run it in an async function, simply because you do not know how long it will take until chrome has started. so with

const pupeteer = require('puppeteer') const page; (async () => {
    // Init Pupeteer
    const browser = await pupeteer.launch({ headless: false });
    const page = await browser.newPage(); // New Page to be manipulated

    // Automation

    // Close Browser
    await browser.close();

We start our browser. The flag headless is set to ‘true’ as default, however for debugging purposes, you should set it to ‘false’;


To Login to the site we need three things:

  • The URL for the Login Page
  • CSS Selector for the Username Field
  • CSS Selector for the Password Field

To obtain the selectors you can use the Chrome DevTools (F12). Simply select the HTML Field and with Rightclick select Copy Selector.

async function  logIn(){
    let LOGIN_URL = '';
    await page.goto(LOGIN_URL);
    await page.focus('#username');
    await page.keyboard.type(USERNAME);
    await page.focus('#password');
    await page.keyboard.type(PASSWORD);
    await page.waitForNavigation();
    console.log("LOGIN COMPLETE");

Now since you are logged in to the site, you can navigate to any site and fetch all the links.

async function analysePage(){
    let PAGE_URL = ''
    await page.goto(PAGE_URL);
    let links = await page.evaluate(() => {
        return Array.from(document.querySelectorAll('a')).map((val) => val.href);

Final Code

import pupeteer from 'puppeteer'; 
//Node Version < 9 
//const pupeteer = require('puppeteer')

const USERNAME = 'user';
const PASSWORD = 'user';

const page; 

(async () => {
    // Init Pupeteer
    const browser = await pupeteer.launch({ headless: true});
    const page = await browser.newPage();

    // Automation

    // Close Browser
    await browser.close();

async function logIn(){
    let LOGIN_URL = '';
    await page.goto(LOGIN_URL);
    await page.focus('#username');
    await page.keyboard.type(USERNAME);
    await page.focus('#password');
    await page.keyboard.type(PASSWORD);
    await page.waitForNavigation();
    console.log("LOGIN COMPLETE");

async function analysePage(){
    let PAGE_URL = ''
    await page.goto(PAGE_URL);
    let links = await page.evaluate(() => {
        return Array.from(document.querySelectorAll('a')).map((val) => val.href);

Image: Designed by Freepik

DEV281x: Introduction to ReactJS

I took a quick look at Microsoft Introduction to ReactJS, not to actually learn React, but to evaluate how good the materials are for a beginner to learn React.

tl;dr Avoid the assessment. Maybe use create-react-app instead of codepen. Covers the basics quite well.

Lesson 01 | JSX and React Components

Instead of using “create-react-app” as a starting point, the course tells you to go to codepen to check out react.

I guess that makes it a little more focused on the React concepts and less focused on all the surrounding technologies that are needed in a production environment.

After that, it covers the basics of ReactJS, and JSX.

If you are a beginner you probably want to check out create-react-app.

Lesson 02 | State, Life Cycle and Event Handlers

I think the chapter covers the basics quite well. Nothing really to add here.

Lesson 03 | Lists and Forms

I think it is very nice that they cover the basics of handling multiple Form Elements with a generic handler.



The Assessment is quite theoretical and asks rather complicated questions. These questions are especially hard if you have already worked with React as you would never even try to build something in that way.

As a beginner, I would completely skip the assessment. It does not help your understanding of React. It actually also confronts you with bad practices, while inferring that this would be the way how you would actually do things


If you use create-react-app with vscode I think you would have a much better starting experience. The course is great to get started with ReactJS if you avoid the assessments and rather just experiment with your own code base.


ImageDesigned by Freepik

package.json: Updating Fixed Versions with npm-check

One of the common problems when running a larger project is that you need to use fixed versions in your package.json file. But at the same time you need to regularly update your packages. The most elegant way is using npm-check. The small tool allows you to select which packages should get an update and update accordingly.


npm i -g npm-check


To update the packages in your project you now simply run npm-check -u. If you want to ensure that you are installing the exact package run it with the additional optional flag -E to ensure exact-versions.

npm-check -u -E

With Space you select the packages and with Enter you install the package.


ImageDesigned by Freepik

Elementary: Changing the Layout of the Window Controls

While Elementary focuses a lot on UI and is beautiful to use. It is totally mind-boggling that they decided to remove the minimize button.

By changing the value for “gsettings set org.pantheon.desktop.gala.appearance button-layout” you can adjust the button layout to your preference. The value would be in the format of [leftElements] : [ rightElements ]

So the default Elementary setting would be:

gsettings set org.pantheon.desktop.gala.appearance button-layout close:maximize

While the Windows Layout would be

gsettings set org.pantheon.desktop.gala.appearance button-layout :minimize,maximize,close

Sadly the official Elementary Apps do not support this setting, so a program like VSCode would have its Icons on the correct side, while the Pantheon-files still has the same button Layout as before. But well it is a good start.

Disable the package-lock.json file

With NPM 5, npm has started to create a “package-lock.json” file. It ensures that some dependency tree is identical on every developer’s environment. Official Documentation.

Now, that may be important on some projects. In my personal projects, I do not really care. And in the professional projects, I did not have any issues how things were done before.

Actually, with the new way of doing things, you must first remove the package-lock.json file and then run “npm update” to install newer versions of stuff. Then again, this can cause problems as when some other person also creates the package-lock file, or a merge conflict occurs etc. In the end, totally defeating the purpose of the file.

Disabling the Package Lock File for a Project

  1. Create a file called .npmrc
  2. Open the file and add the line package-lock=false

Global Disable

If you currently want to disable the behavior on all projects run

npm config set package-lock false

In the future, the feature may be more easy to use. For now, I at least will stick to the old way of how to do things.

Image: Designed by Freepik

Git: Hooks run `npm install` on checkout

When working on a project you usually install various packages from NPM. Of course, these packages are maintained and updated, adding more features and security fixes, and stability patches.

One person on your team should run npm outdated once per week to see what all has been updated and test if you can integrate the packages into your project. Thus the package.json is updated and causes a grand problem for all other developers on the project. If a package has major breaking changes the code will need to be adjusted, however, that code will not run on the other developer’s environment. The other developers working on the project they have to run npm update to install the missing/outdated packages in their environment.

The solution to this problem is “git hooks”, essentially git can execute code on specific events, like before committing your code, or pre-push etc. git hooks. For my use case, I would like to run npm update after a developer checks out from the git repository, this is the event “post-checkout”.

Native Git Hooks

To create a git hook you need to add a file to your project called .git/hooks/post-checkout (On Linux add the executable bit with chmod +x)

echo "[post-checkout hook: $1]"

changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"

check_run() {
  echo "$changed_files" | grep -E --quiet "$1" && eval "$2"

check_run package.json "npm update"

exit 0 #Needed so Visual Studio Code does not display an error

You will test this and say, yes this works as intended – let’s commit it to the repository. – Now you will discover that you cannot commit files in .git to the repository. In fact, git does not allow you to do this, due to security concerns as git hooks can execute any shell script.

The workaround for this issue is to simply add it into a folder called git-hooks/ and tell the developers to copy the file when they set up their dev environment.


As always if there is a Problem for development with javascript there is an npm package to solve the problem. Huskyuses the package.json to define the scripts that are executed via git hooks. Simply Install Husky npm install husky -D

Then edit the package.json:

    "name" : "test Project"
    "scripts": {
          "postmerge": "npm update"

The Husky solution would also allow you to execute your own js file, maybe also doing some cleanup of files or running tests etc.

Image: Designed by Freepik