Kiwi is free open source project that brings macOS-inspired features for GNOME. *Note. This extension is tested with vanilla GNOME Adwaita theme. Be aware that other extensions may cause compatibility issues. Features: - macOS-style window control buttons with GTK theming - Firefox and Thunderbird window control theming - Move fullscreen windows to new workspaces automatically - Make windows transparent while moving - Display battery percentage when below 20% - Move calendar to the right side and customize notifications - Quick settings media and notifications tweaks - Show current window title in the top panel - Show panel on hover in fullscreen mode - Hide minimized windows in overview - Hide the Activities button - Skip overview on login (go directly to desktop) - Set panel transparency or blur based on window position - Dash-to-dock blur effect - Overview wallpaper blur - Keyboard indicator styling - Focus on newly launched windows (removes window-ready notifications) - Show Caps Lock/Num Lock indicators in the top panel - Add username display to the quick settings menu - Multilingual support and more... This extension uses a modular architecture for stability and customization. Some advanced features require native libraries (available in the advanced/ folder). Disclaimer: This extension is unofficial and not affiliated with Apple in any way.
Note: Binary files aren't shown on the web site. To see all files, please download the extension zipfile.
EGO015 warning
signals connected by extension should be disconnected in disable()
Signals assigned in `enable()` are missing matching disconnect calls in `disable()` or its helper methods.
apps/batteryPercentage.js:94
this._propertiesChangedId = this._batteryProxy.connect('g-properties-changed', () => {
this._updateBatteryPercentage();
})
apps/windowControls.js:84
this._box.connect('leave-event', () => {
this._isContainerHovered = false;
this._updateAllIcons();
return Clutter.EVENT_PROPAGATE;
})
apps/windowControls.js:75
this._box.connect('motion-event', () => {
if (this._suppressHoverUntilPointerMove) {
this._suppressHoverUntilPointerMove = false;
this._updateAllIcons();
}
return Clutter.EVENT_PROPAGATE;
})
apps/windowControls.js:149
this._closeButton.connect('clicked', () => {
const window = global.display.focus_window;
if (window) window.delete(global.get_current_time());
})
apps/windowControls.js:124
this._maximizeButton.connect('clicked', () => {
const window = global.display.focus_window;
if (window) {
if (window.is_fullscreen()) {
window.unmake_fullscreen();
} else if (window.maximized_horizontally && window.m
apps/windowControls.js:119
this._minimizeButton.connect('clicked', () => {
const window = global.display.focus_window;
if (window) window.minimize();
})
apps/windowControls.js:93
button.connect('button-press-event', () => {
button.add_style_pseudo_class('active');
this._updateButtonIcon(buttonType);
})
apps/windowControls.js:97
button.connect('button-release-event', () => {
button.remove_style_pseudo_class('active');
this._updateButtonIcon(buttonType);
})
apps/windowControls.js:102
button.connect('enter-event', () => {
if (this._suppressHoverUntilPointerMove) {
this._suppressHoverUntilPointerMove = false;
}
if (this._useMacosIcons) {
this._isContainerHovered = true;
apps/windowControls.js:111
button.connect('leave-event', () => {
if (this._useMacosIcons) {
this._isContainerHovered = false;
this._updateAllIcons();
}
})
apps/windowControls.js:92
button.connect('notify::hover', () => this._updateButtonIcon(buttonType))
apps/windowTitle.js:54
this._menu.connect('open-state-changed', (menu, isOpen) => {
if (isOpen) {
this._updateRestoreMenuItem();
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this._syncMenuAlignment();
return GLib.SOURCE_REMOVE;
EGO014 warning
objects created by extension should be destroyed in disable()
Objects assigned in `enable()` are missing matching `.destroy()` calls in `disable()` or its helper methods.
apps/batteryPercentage.js:15
this._batteryLabel = new St.Label({
style_class: 'battery-percentage-label',
text: '',
opacity: 0,
y_align: Clutter.ActorAlign.CENTER
})
EGO027 warning
owned object references should be released in disable()
Owned references that are cleaned up in `disable()` should also be released with `null` or `undefined`.
apps/batteryPercentage.js:15
this._batteryLabel = new St.Label({
style_class: 'battery-percentage-label',
text: '',
opacity: 0,
y_align: Clutter.ActorAlign.CENTER
})
EGO030 warning
extensions should avoid synchronous file IO in shell code
Shell code should avoid synchronous file IO APIs like `GLib.file_get_contents()` and `Gio.File.load_contents()`.
apps/mozillaThemeManager.js:278
file.load_contents(null)
apps/overviewWallpaper.js:110
file.load_contents(null)
apps/overviewWallpaper.js:151
file.load_contents(null)
EGO-C49-003 error
extensions targeting GNOME 49 must not call maximize or unmaximize with Meta.MaximizeFlags
This extension explicitly targets GNOME Shell 49 but still passes `Meta.MaximizeFlags` to `maximize()` or `unmaximize()`.
apps/windowControls.js:135
window.unmaximize(Meta.MaximizeFlags.BOTH)
apps/windowControls.js:143
window.maximize(Meta.MaximizeFlags.BOTH)
apps/windowTitle.js:199
win.unmaximize(Meta.MaximizeFlags.BOTH)
EGO-C49-004 error
extensions targeting GNOME 49 must not call Meta.Window.get_maximized
This extension explicitly targets GNOME Shell 49 but still calls removed `Meta.Window.get_maximized()`.
apps/windowControls.js:302
win.get_maximized()
apps/windowControls.js:363
focusWindow.get_maximized()
apps/windowTitle.js:174
win.get_maximized()
EGO016 warning
main loop sources should be removed in disable()
Main loop sources assigned in `enable()` are missing matching removals in `disable()` or its helper methods.
apps/windowTitle.js:151
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this._syncMenuAlignment();
return GLib.SOURCE_REMOVE;
})
apps/windowTitle.js:57
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this._syncMenuAlignment();
return GLib.SOURCE_REMOVE;
})
| Version | Status |
|---|---|
| 1.6.2 (43) | Active |
| 1.6.1 (42) | Rejected |
| 1.5.5 (41) | Active |
| 1.5.5 (40) | Rejected |
| 1.5.5 (39) | Rejected |
| 1.5.4 (38) | Inactive |
| 1.5.4 (37) | Rejected |
| 1.5.3 (36) | Active |
| 1.5.3 (35) | Rejected |
| 1.5.2 (34) | Active |
| 1.5.1 (33) | Active |
| 1.5.0 (32) | Inactive |
| 1.4.1 (31) | Active |
| 1.4.1 (30) | Rejected |
| 1.4.0 (29) | Active |
| 1.4.0 (28) | Rejected |
| 1.3.1 (27) | Active |
| 1.3.0 (26) | Active |
| 1.2.1 (25) | Active |
| 1.2.1 (24) | Rejected |
| 1.2.0 (23) | Active |
| 1.1.0 (22) | Active |
| 1.0.2 (21) | Inactive |
| 1.0.1 (20) | Inactive |
| 1.0.0 (19) | Inactive |
| 18 | Inactive |
| 17 | Inactive |
| 16 | Rejected |
| 15 | Inactive |
| 0.9.6 beta (14) | Rejected |
| 13 | Inactive |
| 12 | Inactive |
| 11 | Inactive |
| 10 | Inactive |
| 9 | Inactive |
| 8 | Inactive |
| 7 | Rejected |
| 6 | Inactive |
| 5 | Rejected |
| 4 | Inactive |
| 3 | Rejected |
| 2 | Inactive |
| 1 | Rejected |
EGO014 and EGO027 are false positives EGO-C49-004 and EGO-C49-003 flags compatibility fallbacks as errors. The code is already properly structured for multi-version support, with one minor exception in windowTitle.js.