Skip to content

arimourao/cinnamon

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9,308 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cinnamon

Overview

Cinnamon is a Linux desktop environment maintained by the Linux Mint team. Its goal is straightforward: provide a desktop that looks and behaves the way most people expect — a taskbar at the bottom, a traditional application menu, windows with title bars, system tray icons — while running on a modern, composited graphics stack.

It was created in 2011 as a reaction to GNOME 3, which replaced that familiar layout with a fullscreen activity-based interface. Cinnamon forked GNOME Shell's codebase and kept the underlying technology but rebuilt the user-facing layer to stay conventional. That lineage is still visible today: Cinnamon shares DNA with GNOME at the compositor and runtime level, but diverges completely at the UI layer.

What problem it solves

A desktop environment is the software layer between the Linux kernel and the user. It manages windows, renders the panel and menus, handles keyboard shortcuts, draws notifications, and coordinates everything from the screensaver to the network indicator. Without it, you have a blank screen with a cursor. Cinnamon's specific proposition is to do all of that while keeping the interface familiar, stable, and unobtrusive — the desktop should not demand attention, it should get out of the way.

How it is built

Cinnamon is not a single program. It is a process that simultaneously acts as a window compositor and a desktop shell, plus a set of companion applications:

Layer Technology Role
Compositor C + Muffin Renders windows, manages focus and workspaces. Muffin is Linux Mint's fork of Mutter (GNOME's compositor).
Shell UI JavaScript via CJS Drives everything the user sees: panels, menus, notifications, overview. CJS is a fork of GJS (GNOME JavaScript), which uses Mozilla's SpiderMonkey engine — the same as Firefox. No Node.js involved.
Widget toolkit C (St / Shell Toolkit) A CSS-styleable actor library built on Clutter. Every shell widget is an St actor.
Theme SCSS → CSS Compiled at build time by sassc into a single stylesheet consumed by St.
Settings app Python 3 + PyGObject A standalone GTK3 application. Communicates with the running shell over D-Bus.
GObject bridge GObject Introspection Lets JS and Python call into C libraries (GTK, GLib, Muffin, etc.) without hand-written bindings. Used by all three language layers.

The build system is Meson, which generates Ninja build files. Ninja orchestrates the actual compilation, calling GCC for the C code and sassc for the SCSS. JS and Python files are plain text — they are installed as-is and require no compilation.

Licensed under the GNU General Public License, version 2 or later.



Requirements

  • Linux (X11 session; Wayland support is in-progress behind a build flag)
  • GLib ≥ 2.79.2
  • GTK+ 3 ≥ 3.12.0
  • Muffin / libmuffin-0 ≥ 5.2.0 (provides Clutter, COGL, and the compositor)
  • CJS ≥ 115.0
  • GObject Introspection (girepository-2.0 or gobject-introspection-1.0)
  • libcinnamon-menu ≥ 4.8.0
  • GCR 3 ≥ 3.7.5
  • Polkit ≥ 0.100
  • XApp ≥ 2.6.0
  • libxdo, libpam, libxml-2.0, dbus-1, x11, xcomposite, xext, GL
  • Python 3 (for the settings app and install scripts)
  • Optional: libnm ≥ 1.10.4 + libsecret ≥ 0.18 (built-in network agent), GStreamer 1.0 (screen recorder)

All Muffin, CJS, XApp, and cinnamon-menus packages must come from the same Linux Mint release branch as Cinnamon itself.

Installation

Linux Mint (recommended)

Cinnamon is the default desktop on Linux Mint and is pre-installed. To reinstall:

sudo apt install cinnamon

Ubuntu

sudo apt install cinnamon

The version in Ubuntu's repositories is packaged and maintained by Ubuntu, not Linux Mint. It will generally be older than the current Linux Mint release and may behave differently in edge cases. For a closer-to-upstream experience on Ubuntu, use a Linux Mint VM instead.

Debian

sudo apt install cinnamon

Cinnamon is available in Debian's main repositories since Debian 10 (Buster). Same caveat as Ubuntu: the packaged version tracks Debian's release cycle, not Linux Mint's.

Arch Linux

sudo pacman -S cinnamon

Other distros

Check your distribution's package repository for a package named cinnamon. If it is not available, or the version is too old, building from source is the alternative — see Building from source.

From source

See Building from source below. Note that building from source requires all sibling Linux Mint components (Muffin, CJS, XApp, etc.) to also be built or installed from the same branch.

Building from source

1. Install build dependencies

sudo apt build-dep cinnamon
sudo apt install meson ninja-build

apt build-dep reads the package metadata and pulls in exactly the right set of -dev libraries for the version of Cinnamon that is currently in your distro's repositories. It is more reliable than maintaining a manual list. If deb-src lines are not enabled in /etc/apt/sources.list, enable them first:

sudo sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list
sudo apt update

2. Configure

meson setup build --prefix=/usr

This generates the actual build files inside build/. Meson is a meta-build system: it does not compile anything itself. Instead it reads meson.build, resolves dependencies via pkg-config, and writes a set of Ninja files that describe exactly which files to compile, in which order, with which flags.

Ninja is the build tool that executes those instructions — the equivalent of make, but faster and with no language of its own. It calls GCC (or Clang) for the actual C compilation. The chain is: Meson generates the plan → Ninja runs the plan → GCC compiles the C files. You never call GCC directly.

Common options:

Flag Default Effect
-Ddocs=true false Build gtk-doc API references
-Dwayland=true true Enable Wayland session support
-Dnm_agent=internal internal internal, external, or disabled
-Dbuild_recorder=false true Exclude screen recorder (drops GStreamer dep)

3. Compile and install

ninja -C build
sudo ninja -C build install

4. Run tests

ninja -C build test

The test suite is minimal (three JS unit tests covering string formatting, markup, and URL parsing). Visual verification against a running session is the primary testing method.

Architecture overview

Cinnamon runs as a single process that is simultaneously a Wayland/X11 compositor (via Muffin) and the desktop shell. The C layer (src/) defines native GObject types — window tracker, app system, screen recorder, policy-kit agent — which are exposed to JavaScript through GObject Introspection as imports.gi.Cinnamon.*. The JavaScript layer (js/) drives everything the user sees: panels, applets, the overview, notifications, and workspace management; js/ui/main.js is the bootstrap entry point called by the C process after Clutter initialises. The St widget library (src/st/) provides CSS-styleable Clutter actors used by both C and JS code. Python 3 (python3/) implements the Cinnamon Settings application and installer tooling; it communicates with the running shell over D-Bus.

Working on an issue

The safe setup: use a virtual machine

Do not develop Cinnamon inside your main desktop session. The shell and the compositor are the same process. A bug introduced in C or JS can black out the screen, freeze input, or corrupt the session — and cinnamon --replace will not save you if the new binary crashes on startup.

The recommended setup is a Linux Mint VM (VirtualBox, GNOME Boxes, or libvirt/KVM) running the same release branch as the code you are targeting. Make all changes there. Your host desktop is never at risk.

If you choose to develop on a physical machine anyway, keep a TTY available (Ctrl+Alt+F2) and know how to restore a working binary from there.


Working on JavaScript

What runs the JS — and it is not Node.js

Cinnamon's JavaScript has nothing to do with Node.js, npm, or any browser-based runtime. There is no package.json, no node_modules, no bundler, no transpiler.

The JS files in js/ run inside the Cinnamon process itself, interpreted by CJS (linuxmint/cjs) — a fork of GJS (GNOME JavaScript) that uses SpiderMonkey, the same engine as Firefox. CJS is installed as a system package alongside Cinnamon. When Cinnamon starts, it launches CJS internally; your JS code runs there, with direct access to C libraries through GObject Introspection (imports.gi.*).

The practical consequence: you do not install or manage a JS runtime. If Cinnamon is installed and running, the runtime is already present.

Prerequisites for JS work

  • A Linux Mint VM with Cinnamon running (X11 session)
  • git to clone the repo
  • A text editor

That is all. No compiler, no build tools, no language toolchain to install.

Workflow

JS files are installed as plain text to /usr/share/cinnamon/js/. Editing them there takes effect on the next shell restart, with no compilation step:

# 1. Edit a file directly in the installed location
sudo nano /usr/share/cinnamon/js/ui/panel.js

# 2. Restart the shell in-place (X11 only, ~2 seconds, no logout needed)
cinnamon --replace &

If you prefer to work from a git clone and keep changes tracked:

git clone https://github.com/linuxmint/cinnamon.git
cd cinnamon

# Edit js/ui/panel.js (or whichever file), then copy it over:
sudo cp js/ui/panel.js /usr/share/cinnamon/js/ui/panel.js
cinnamon --replace &

Reading JS errors

Errors, exceptions, and log() output go to the journal:

journalctl -f /usr/bin/cinnamon

The shell usually does not crash on a JS error — it logs it and continues, sometimes with degraded functionality. If a module fails to load entirely, the affected component (e.g. the panel) will simply not appear.

Static checker

Before restarting, run the checker included in the repo. It catches two patterns that crash the shell without a useful error message:

# Run from the repo root or from /usr/share/cinnamon
python3 utils/check-js

It reports duplicate let declarations in the same scope (SpiderMonkey crash) and missing commas between prototype methods (silent startup failure).

Looking Glass — the interactive JS debugger

Cinnamon ships a built-in developer console called Looking Glass. Open it from a running session with Alt+F2, type lg, press Enter. It gives you:

  • A live JS REPL evaluated inside the running Cinnamon process
  • A log viewer (same output as journalctl)
  • An object inspector for actors and GObject instances
  • An extensions/applets tab showing load errors

This is the fastest way to inspect shell state, test a one-liner, or confirm that a module loaded correctly — without restarting anything. Looking Glass itself is a Python+GTK application (files/usr/share/cinnamon/cinnamon-looking-glass/), but what it executes runs inside the live CJS context.


Working on C

What is involved

The C layer (src/) compiles to a shared library (libcinnamon.so) and the cinnamon binary. Unlike JS, any change here requires a full compile-and-install cycle before it can be tested. The toolchain is: Meson (build configurator) → Ninja (build runner) → GCC (compiler). You never call GCC directly — Meson generates a build plan and Ninja executes it, calling GCC for each C file that needs recompilation.

Prerequisites for C work

# Enable source repositories so apt can read build dependency metadata
sudo sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list
sudo apt update

# Install all build dependencies declared by the package in one command
sudo apt build-dep cinnamon

# Install the build tools themselves
sudo apt install meson ninja-build git

apt build-dep is more reliable than a manual list: it reads the package metadata for the version of Cinnamon in your distro's repositories and pulls in the exact set of -dev libraries needed.

First-time setup

git clone https://github.com/linuxmint/cinnamon.git
cd cinnamon

# Configure the build (run once)
meson setup build --prefix=/usr

--prefix=/usr installs over the system Cinnamon inside the VM. All .typelib files, GSettings schemas, and session files land in the right locations automatically. Installing to a custom prefix requires manually exporting GI_TYPELIB_PATH, XDG_DATA_DIRS, and other env vars.

Workflow

# Edit src/*.c or src/*.h, then:
ninja -C build                 # recompiles only changed files (usually a few seconds)
sudo ninja -C build install    # installs the new binary and shared library
cinnamon --replace &           # loads the new binary into the running session

Ninja is incremental: on the second run it compares timestamps and recompiles only what changed. A single .c file typically takes under ten seconds. The --replace step picks up the new binary without ending the X session.

Crash recovery inside the VM

If cinnamon --replace fails and the desktop disappears:

  1. Switch to a TTY: Ctrl+Alt+F2
  2. Log in
  3. Revert the change and rebuild, or reinstall the package: sudo apt install --reinstall cinnamon
  4. Start the shell from the TTY: DISPLAY=:0 cinnamon --replace &
  5. Return to the graphical session: Ctrl+Alt+F7 (or F1, depending on the display manager)

Debugging crashes

# Attach GDB to a running cinnamon process and dump a backtrace on crash:
utils/cin-debug cinnamon

# Or launch cinnamon under GDB from the start:
utils/cin-debug-run cinnamon

Both scripts write a timestamped log to ~/cinnamon-<timestamp>.log with a full backtrace for every thread at the moment of the crash.


Working on Python

What uses Python

Python 3 accounts for roughly 18% of the codebase. The main pieces are:

Path What it is
files/usr/share/cinnamon/cinnamon-settings/ The Cinnamon Settings application
files/usr/share/cinnamon/cinnamon-looking-glass/ The Looking Glass debugger
files/usr/share/cinnamon/cinnamon-desktop-editor/ .desktop file editor
files/usr/share/cinnamon/cinnamon-settings-users/ User account settings panel
python3/cinnamon/ Library for downloading and updating Spices (applets, themes, extensions)

All Python code uses PyGObject (gi) — the same GObject Introspection bridge used by CJS, but for Python. Accessing GTK, GLib, or XApp from Python looks like this:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio, GLib

There is no virtualenv, no requirements.txt, and no pip. All dependencies (gi, requests, PIL/Pillow, setproctitle, pyinotify) are system packages installed via apt.

Prerequisites for Python work

sudo apt install python3-gi python3-gi-cairo gir1.2-gtk-3.0 \
                 python3-pil python3-requests python3-setproctitle python3-pyinotify

Workflow

Python files are also installed as plain text — no compilation step. Edit the file, relaunch the affected application:

# Example: editing the settings app
sudo nano /usr/share/cinnamon/cinnamon-settings/cinnamon-settings.py

# Relaunch it directly (it is a standalone GTK app, not part of the shell process)
cinnamon-settings

The settings app and other Python tools run as separate processes from the Cinnamon shell. A crash or error there does not affect the desktop session. You can run them directly from a terminal and see tracebacks immediately — no journal needed, no --replace.


Working on SCSS / theme

What SCSS is used for

The default Cinnamon theme lives in data/theme/cinnamon-sass/. It is written in SCSS and compiled to a single cinnamon.css file at build time. That CSS is loaded by the St (Shell Toolkit) widget library to style every shell component: panels, menus, notifications, the calendar, the alt-tab switcher, and so on.

St's CSS is not browser CSS. It implements a subset: box model, colours, fonts, borders, padding, and a few St-specific properties. Animations are handled separately in JS/C code.

The SCSS is structured as:

cinnamon.scss         ← entry point, imports everything
_colors.scss          ← colour variables
_drawing.scss         ← reusable drawing mixins
_common.scss          ← shared base styles
_widgets.scss         ← imports per-widget files
widgets/
  _panel.scss
  _menus.scss
  _notifications.scss
  ... (one file per shell component)

Prerequisites for SCSS work

The build requires either sassc (C implementation) or pysassc (Python wrapper):

sudo apt install sassc

Workflow

SCSS changes require a build step to produce the CSS, but only the theme target needs to rebuild — not the entire project:

# Recompile only the theme
ninja -C build data/theme/cinnamon-sass/cinnamon.css
sudo ninja -C build install

# Reload the theme without restarting the shell
gsettings set org.cinnamon.theme name ""          # clear
gsettings set org.cinnamon.theme name "cinnamon"  # reapply

If the theme name trick does not trigger a reload, cinnamon --replace & always works as a fallback.

To iterate quickly without Meson, you can also compile SCSS manually and copy the result:

sassc data/theme/cinnamon-sass/cinnamon.scss /tmp/cinnamon.css
sudo cp /tmp/cinnamon.css /usr/share/cinnamon/theme/cinnamon.css
# then reload via gsettings or --replace

Contributing

  • Bug reports and feature requests: https://github.com/linuxmint/cinnamon/issues
  • Related components (Muffin, CJS, cinnamon-settings-daemon, etc.): https://projects.linuxmint.com/cinnamon/
  • Coding style: Follow the conventions of the surrounding code. C code uses GObject patterns; JS uses GObject.registerClass() with ES6 classes for new code. No external JS dependencies — all libraries come through GObject Introspection.
  • Translations: Managed via the po/ directory; do not edit .po files manually — use the Linux Mint translation platform.

Links

About

A Linux desktop featuring a traditional layout, built from modern technology and introducing brand new innovative features.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • JavaScript 42.2%
  • C 38.3%
  • Python 18.1%
  • SCSS 0.8%
  • Meson 0.4%
  • Shell 0.1%
  • Other 0.1%