# GTK-NoCSD

GTK-NoCSD is an LD_PRELOAD library to disable CSD in GTK3/4, LibHandy, and LibAdwaita apps.

CSD is client side decoration, there is also server side decoration, SSD, both serving as the titlebar of windows.  
GTK3 adopted CSD, where this thick headerbar is used with application controls embedded.  
This continued into the platform library, LibHandy, then into GTK4 and the platform library of that, LibAdwaita.  
This looks good on Gnome and makes these applications alike, but looks off everywhere else and can potentially break window managers and remove window manager provided functionality.  
This library restores the server side decoration, getting back the window manager titlebar, and moves the controls from the CSD to under it, into the window content.  

## Build dependencies

- GCC
- LibAdwaita

## Building

### Make

The library uses the make build system.  
Look at ARGUMENTS block to see what can be changed.  
The makefile has the following commands:  

- build: Builds the library
- clean: Removes locally built library
- install: Builds and installs library
- uninstall: Removes installed library
- format: Formats source code with uncrustify

### Manually

Get the source files and enter the directory.  

```
git clone https://codeberg.org/MorsMortium/GTK-NoCSD.git
cd GTK-NoCSD
```

Build the library.  
Both 32 and 64 bit builds will produce a libgtk-nocsd.so.0 file, in the root of the repository.  

#### 64 bit

This command builds the library.  
```
gcc -fPIC -shared ./Source/GTK-NoCSD.c -o libgtk-nocsd.so.0 \
	-Wl,-soname,libgtk-nocsd.so.0 \
	$(pkg-config --cflags libadwaita-1) \
	$(pkg-config --cflags --libs gobject-2.0 gio-2.0)
```

#### 32 bit

Building for 32 bit applications can be done like so.  
```
gcc -fPIC -shared ./Source/GTK-NoCSD.c -o libgtk-nocsd.so.0 \
	-Wl,-soname,libgtk-nocsd.so.0 \
	$(pkg-config --cflags libadwaita-1 | sed 's/$/ -m32/') \
	$(pkg-config --cflags --libs gobject-2.0 gio-2.0 | sed 's/$/ -m32/')
```

## Packaging

You are free to package it yourself or ask distribution packagers to do it.

### AUR

https://aur.archlinux.org/packages/gtk-nocsd-git  

### Gentoo

```
eselect repository enable overlay-from-plan9
emaint sync -r overlay-from-plan9
emerge -av gui-libs/gtk-nocsd
```

### Fedora

```
sudo dnf copr enable hazel-bunny/ricing
sudo dnf upgrade
sudo dnf install gtk-nocsd
```

## Usage

Here the naming was written for a file named libgtk-nocsd.so, available in the packages.  
If manual build was used and the file is named libgtk-nocsd.so.0, it can either be renamed to libgtk-nocsd.so or the instructions can be changed to the new name.  

`LD_PRELOAD=./libgtk-nocsd.so app`
The path can be an absolute path. If only `LD_PRELOAD=libgtk-nocsd.so` is used, it is possible that the binary changes current directory and preloading fails.

For help on setting up individual applications, I recommend my similar setup: https://codeberg.org/MorsMortium/Setup/src/commit/ef00c78e848d88ac0f6d8b426034c672863feacc/UserSetup.sh#L48  
Bear in mind the segment after, where .desktop files get their `DBusActivatable=true` part removed, which fixes them not picking up the library.  
There is also a manual guide: [SingleAppUsage.md](./SingleAppUsage.md)  

The library works globally too, usage combined with gtk3-nocsd is not supported (but also not needed).  
To use it globally, add `export LD_PRELOAD=/path/to/libgtk-nocsd.so` to `~/.bash_profile`, or in case of other system shell, the profile of that.  
When loaded globally, the `DBusActivatable=true` removal is not needed.  

Certain launchers or .desktop files start the application with `gapplication launch` which might not carry the LD_PRELOAD variable.  
this can be solved by creating a ` ~/.config/environment.d` folder, in that a .conf file, the name should not matter, for example `LD_PRELOAD.conf` and in that as content `LD_PRELOAD=/path/to/libgtk-nocsd.so`.  
After a restart these applications or applications started from these launchers will pick up the variable.  

### Nix Home Manager

Applications installed through this might not have access to the needed libraries.  
This is apparent from the following error:
```
error while loading shared libraries: libgio-2.0.so.0: cannot open shared object file: No such file or directory
```
There are multiple possible solutions for this, depending on applications and setups.  
If all the applications that need the library are in C or other compiled languages that link dependencies, the library can be built without linking extra libraries like so: `make NOLDFLAGS=1`  
If this is not the case, then if there are more applications needing the library, then the ones that crash with the error need extra setup with disabling the library there (`LD_PRELOAD=""`)  
If there are more that do not need the library, then each individual application needs to be set up individually (as described previously).  

### Flatpak

The library can be used as is.

To do so, the easiest is using Flatseal:  
In the All Applications/Filesystem the folder in which the library is has to be added.  
Remember that /usr cannot be shared, if it is there, it has to be moved or copied somewhere else.  
For the packages using the make method (all listed), /opt/gtk-nocsd/libgtk-nocsd.so is available for flatpak.  
Then, in All Applications/Environment the LD_PRELOAD variable has to be added:  
`LD_PRELOAD=/path/to/libgtk-nocsd.so` This is the same path as what was shared.  
These can be done for a single application as well, if that is needed.  

Testing a single application can be done like so:  
`flatpak run --filesystem=/path/to/ --env=LD_PRELOAD=/path/to/libgtk-nocsd.so org.developer.application`

Setting up all applications:  
`flatpak override --user --filesystem=/path/to/ --env=LD_PRELOAD=/path/to/libgtk-nocsd.so`

Setting up a single application:  
`flatpak override --user --filesystem=/path/to/ --env=LD_PRELOAD=/path/to/libgtk-nocsd.so org.developer.application`

Resetting modifications (either done by Flatseal or these commands):  
All applications: `flatpak override --user --reset`  
A single application: `flatpak override --user --reset org.developer.application`  

## Testing

The library was tested and working with the following applications

### GTK4 and LibAdwaita

- Gnome games
	- Mahjongg
	- Sudoku
	- Mines
	- Nibbles
	- Chess
	- Swell Foop
	- Robots
	- Lights Off
	- Quadrapassel
- Development tools
	- Demo
	- Node Editor
	- Widget Factory
	- Cambalache
	- Adwaita Demo
- Android Translation Layer
- Font Manager
- Dino
- Easy Effects
- vipsdisp
- Gajim
- Mission Center
- Gnome Calls
- Pidgin 3
- Lenspect
- Aether (with using `gjs -m /usr/share/aether/src/main.js` directly (or possibly in `/etc/ld.so.preload`))
- Meld (GTK4 port)
- Pamac

### GTK3 and LibHandy

- Gnome games
	- 2048
	- Five or More
	- Four in a Row
	- Hitori
	- Klotski
	- Tetravex
	- Taquin
	- Atomix
	- Iagno/Reversi
- Development tools
	- Demo
	- Widget Factory
	- Icon Browser
	- Glade
- Lutris
- BleachBit
- SongRec
- Gnome-Pie
- Trackma
- Emote
- HardInfo2
- Pamac (LibHandy version)

The library is intentionally disabled for GTK Inspector windows.
There are no known applications where this does not work.

## Screenshots

### Before

![](./Images/Old1.png)
![](./Images/Old2.png)
![](./Images/Old3.png)
![](./Images/Old4.png)
![](./Images/Old5.png)

### After

![](./Images/New1.png)
![](./Images/New2.png)
![](./Images/New3.png)
![](./Images/New4.png)
![](./Images/New5.png)

## Theming

### GTK3/GTK4

As usual.

### LibHandy/LibAdwaita

Set GTK_THEME variable to theme (folder in `/usr/share/themes` or `~/.themes`).

### Inside flatpak

Copy `/usr/share/themes` to `~/.themes` in case of system theme.  
Pass through `~/.themes` folder to flatpak with `--filesystem=~/.themes`.  
Set theme name with environment variable `--env=GTK_THEME=Breeze:dark`.  
`:dark` is dark preference, `:whatever else` is light preference.  
Not having either (`--env=GTK_THEME=Breeze`) is leaving it to the default.  

## Contributions

### Contributions are welcome!

Rules of contribution:

- Use the naming conventions (PascalCase everywhere, no shortening of words)
- Format the code with uncrustify, which can be done with running this command in the root directory: `uncrustify -c ./Uncrustify.cfg --replace ./Source/*.c`
- Keep 80 characters line length (handled by uncrustify in C)
- Never call GTK/GDK functions that don't start with o_, unless own function. (GObject/GLib and such are fine)
- If own replacement function is called comment `// WARNING: Own call`
- If having to cast between signed and unsigned or larger to smaller, add `// WARNING: Downcast`
- Avoid GTK/GDK macros, if possible
- The build should not produce any warnings

## Support

### Never open issues for GTK/Gnome apps, when this library is in use.

If you have any problem with any apps, that is caused by this library, report it here.
If there is an issue with an app, that is not caused by the library, make all reports/investigations with the library disabled.
The library won't have a dedicated chat, but feel free to join our Matrix community https://matrix.to/#/%23TheWorldMachineOffTopic%3Amatrix.org?via=matrix.org&via=midov.pl&via=monero.social

## Donation

If you like my work, feel free to donate: https://morsmortium.neocities.org/donation
