Skip to content

Commit

Permalink
feat: ✨ added option to set a custom icon theme
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Jun 5, 2020
1 parent e40bb3c commit f61ca71
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 13 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ iconSize=40
#Full path to a css file, or 'default'.
#See config/themes/default.css
theme=default
#An gtk icon theme name, or 'default'
iconTheme=default

[behavior]
#Specify a list of keys to group windows on: class;instance;title;visibility
Expand Down
2 changes: 2 additions & 0 deletions config/settings.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ iconSize=40
#Full path to a css file, or 'default'.
#See config/themes/default.css
theme=default
#An gtk icon theme name, or 'default'
iconTheme=default

[behavior]
#Specify a list of keys to group windows on: class;instance;title;visibility
Expand Down
6 changes: 6 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const defaults = {
offsetY: 0,
iconSize: 40,
theme: "default",
iconTheme: "default",
},
behavior: {
groupBy: ["instance", "visibility"] as WindowGrouping[],
Expand Down Expand Up @@ -129,6 +130,11 @@ class Config {
"theme",
`Full path to a css file, or 'default'.\nSee config/themes/default.css`
)
ini.set_comment(
"appearance",
"iconTheme",
`An gtk icon theme name, or 'default'`
)
ini.set_comment(
"behavior",
"groupBy",
Expand Down
62 changes: 49 additions & 13 deletions src/dock-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import GdkPixbuf from "./types/GdkPixbuf-2.0"
import GLib from "./types/GLib-2.0"
import Gtk from "./types/Gtk-3.0"
import Wnck from "./types/Wnck-3.0"
import { getXProp, XPropType } from "./xutil"

export class DockItem {
name: string
Expand Down Expand Up @@ -134,28 +135,63 @@ export class DockItem {
}

updateIcon() {
const iconTheme = Gtk.IconTheme.get_default()
let iconName = this.window.get_class_instance_name() || "application"
let iconTheme = Gtk.IconTheme.get_default()
if (
config.settings.appearance.iconTheme &&
config.settings.appearance.iconTheme !== "default"
) {
iconTheme = new Gtk.IconTheme()
iconTheme.set_custom_theme(config.settings.appearance.iconTheme)
}

const cleanup = (iconName: string) => {
if (iconName) {
return iconName.replace(/\s+/gu, "").toLowerCase()
}
}

const lookup: (string | undefined)[] = []

// Load custom icons from config
const groupIcon = cleanup(this.window.get_class_group_name())
const instanceIcon = cleanup(this.window.get_class_instance_name())

lookup.push(
getXProp(
this.window.get_xid(),
"_GTK_APPLICATION_ID",
XPropType.UTF8_STRING
),
instanceIcon
)

const noGroupIcons = ["brave-browser", "chromium-browser", "chrome-browser"]
if (groupIcon && !noGroupIcons.includes(groupIcon)) {
lookup.push(groupIcon)
}

// // Load custom icons from config
for (const [iconK, iconV] of Object.entries(config.settings.icons)) {
if (
iconName.toLowerCase().includes(iconV.toLowerCase()) &&
iconTheme.has_icon(iconK)
iconTheme.has_icon(iconK) &&
lookup.some((x) => `${x}`.includes(iconV.toLowerCase()))
) {
iconName = iconK
break
lookup.unshift(iconK)
}
}

let icon: GdkPixbuf.Pixbuf | null = this.window.get_icon()

if (iconTheme.has_icon(iconName)) {
icon = iconTheme.load_icon(
iconName,
config.settings.appearance.iconSize,
Gtk.IconLookupFlags.FORCE_SIZE
)
const iconNames = lookup.filter((x) => x) as string[]

const iconInfo = iconTheme.choose_icon(
iconNames,
config.settings.appearance.iconSize,
Gtk.IconLookupFlags.FORCE_SIZE
)

if (iconInfo) {
log(`[icon] ${iconInfo.get_filename()}`)
icon = iconInfo.load_icon()
} else {
icon = icon.copy()
if (icon)
Expand Down
2 changes: 2 additions & 0 deletions src/globals.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Object } from "./types/GObject-2.0"
import { byteArray } from "./types/Gjs"

declare global {
const ARGV: string[]
const imports: {
byteArray: byteArray
system: {
gc: () => void
exit: (exitCode) => void
Expand Down
28 changes: 28 additions & 0 deletions src/xutil.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Gdk from "./types/Gdk-3.0"
import GdkX11 from "./types/GdkX11-3.0"

export enum XPropType {
"STRING",
"UTF8_STRING",
"CARDINAL",
"ATOM",
}

export function getXProp(xid: number, prop: string, type: XPropType) {
const window: Gdk.Window = GdkX11.X11Window.foreign_new_for_display(
Gdk.Display.get_default() as GdkX11.X11Display,
xid
)
if (window) {
const [found, _actualType, _actualFormat, data] = Gdk.property_get(
window,
Gdk.atom_intern(prop, false),
Gdk.Atom.intern(XPropType[type], false),
0,
2048,
0
)

if (found) return imports.byteArray.toString(data) as string
}
}

0 comments on commit f61ca71

Please sign in to comment.