Skip to content

Widgets

Widget functions return an instance of Gtk.Widget. Most common widgets are subclassed and have a few additional properties.

These widgets have some additional properties on top of the base Gtk.Widget ones:

PropertyTypeDescription
class-namestringList of class CSS selectors separated by white space.
class-namesArray<string>List of class CSS selectors.
cssstringInline CSS. e.g label { color: white; }. If no selector is specified * will be assumed. e.g color: white; will be inferred as *{ color: white; }.
hpackstringHorizontal alignment, behaves like halign. halign takes an enum, but for convenience hpack can be given with a string, so one of "start", "center", "end", "fill".
vpackstringVertical alignment.
cursorstringCursor style when hovering over widgets that have hover states, e.g it won’t work on labels. list of valid values.
attributeanyAny additional attributes on self
setup(self) => voidA callback function to execute on self

Setup property

setup is a convenience prop to have imperative code inside declarative blocks

without setup

function MyWidget() {
const self = Widget.Button()
// imperative code
return self
}

using setup

const MyWidget = () => Widget.Button({
setup: self => {
// imperative code
}
})

Attribute property

for attaching additional attributes on widgets Object.assign or the attribute property can be used

function MyWidget() {
const self = Widget.Button()
return Object.assign(self, {
myPrimitiveProperty: "anything",
myObjectProperty: {
something: "anything",
key: "value",
},
})
}
const mywidget = MyWidget()
console.log(mywidget.myPrimitiveProperty) // anything
console.log(mywidget.myObjectProperty) // { something: "anything", key: "value" }

using attribute has the benefit of it being a gobject which means it will signal notify::attribute when it changes

const MyWidget = () => Widget.Button({
attribute: "anything",
setup: self => self.on("notify::attribute", () => {
console.log(mywidget.attribute)
}),
})
const mywidget = MyWidget()
console.log(mywidget.attribute) // anything
// this line will invoke the above console.log in the setup
mywidget.attribute = "something else"

keep in mind that attribute will only signal if its value changes

const MyWidget = () => Widget.Button({
attribute: {
someKey: "value",
key: "value",
},
setup: self => self.on("notify::attribute", () => {
console.log(mywidget.attribute)
})
})
const mywidget = MyWidget()
// this line won't signal, because the attribute is still the same object
mywidget.attribute.key = "new value"
// to have it signal, assign a new object to it
mywidget.attribute = {
...mywidget.attribute,
key: "new value"
}

Common Gtk properties

Some common Gtk.Widget properties you might want for example

PropertyTypeDescription
hexpandbooleanExpand horizontally.
vexpandbooleanExpand vertically.
sensitivebooleanMakes the widget interactable.
tooltip-textstringTooltip popup when the widget is hovered over.
visiblebooleanVisibility of the widget. Setting this to false doesn’t have any effect if the parent container calls show_all(), for example when you set a Box’s children dynamically.

toggleClassName

If you don’t want to mutate the classNames array, there is toggleClassName: (name: string, enable: boolean) => void

const label = Widget.Label('example-label')
// add class name
label.toggleClassName('my-awesome-label', true)
// remove class name
label.toggleClassName('my-awesome-label', false)

The properties listed here are just the additional properties on top of their base Gtk.Widget classes. Refer to the Gtk3 docs for the rest of them.

Window

subclass of Gtk.Window

the toplevel widget that holds everything

PropertyTypeDescription
childWidget
namestringName of the window. This has to be unique, if you pass it in config. This will also be the name of the layer.
anchorstring[]Valid values are "top", "bottom", "left", "right". Anchor points of the window. Leave it empty to make it centered.
exclusivitystringSpecify if the compositor should reserve space for the window automatically or how the window should interact with windows that do. Possible values: exclusive (space should be reserved), normal (the window should move if occluding another), ignore (the window should not be moved). Default: normal.
layerstringValid values are "overlay", "top", "bottom", "background". It is "top" by default.
marginsnumber[]Corresponds to CSS notation: [TOP, RIGHT, BOTTOM, LEFT], also [0, 6] would have 0 margin on the top and bottom and would have 6 on the right and left.
monitornumberWhich monitor to show the window on. If it is left undefined the window will show on the currently focused monitor.
keymodestringValid values are "none", "on-demand": can receive keyboard input if focused, "exclusive": steal keyboard input on top and overlay layers
gdkmonitorGdk.Monitoralternative to monitor
const window = Widget.Window({
name: 'window-name',
anchor: ['top', 'left', 'right'],
exclusivity: 'normal',
keymode: 'on-demand',
layer: 'top',
margins: [0, 6],
monitor: 0,
child: Widget.Label('hello'),
})

Box

subclass of Gtk.Box

the main container widget

PropertyTypeDescription
verticalboolsetting vertical: true is the same as orientation: 1
childrenWidget[]List of child widgets.
const box = Widget.Box({
spacing: 8,
homogeneous: false,
vertical: false,
children: [
// widgets
]
})

Button

subclass of Gtk.Button

on-clicked will be executed on Enter if the button and its window has focus

PropertyType
childWidget
on-clicked() => void
on-primary-click(event: Gdk.Event) => boolean
on-secondary-click(event: Gdk.Event) => boolean
on-middle-click(event: Gdk.Event) => boolean
on-primary-click-release(event: Gdk.Event) => boolean
on-secondary-click-release(event: Gdk.Event) => boolean
on-middle-click-release(event: Gdk.Event) => boolean
on-hover(event: Gdk.Event) => boolean
on-hover-lost(event: Gdk.Event) => boolean
on-scroll-up(event: Gdk.Event) => boolean
on-scroll-down(event: Gdk.Event) => boolean
const button = Widget.Button({
child: Widget.Label('click me!'),
onClicked: () => print('hello'),
})

Calendar

subclass of Gtk.Calendar

PropertyTypeDescription
date[number, number, number]readonly [year, month, day]
detail(number, number, number) => string | null
on-day-selected() => void
const calendar = Widget.Calendar({
showDayNames: true,
showDetails: true,
showHeading: true,
showWeekNumbers: true,
detail: (self, y, m, d) => {
return `<span color="white">${y}. ${m}. ${d}.</span>`
},
onDaySelected: ({ date: [y, m, d] }) => {
print(`${y}. ${m}. ${d}.`)
},
})

CenterBox

subclass of Gtk.Box

PropertyTypeDescription
verticalboolsetting vertical: true is the same as orientation: 1
start-widgetGtk.Widget
center-widgetGtk.Widget
end-widgetGtk.Widget
const centerBox = Widget.CenterBox({
spacing: 8,
vertical: false,
startWidget: Widget.Label('left widget'),
centerWidget: Widget.Label('center widget'),
endWidget: Widget.Label('right widget'),
})

CircularProgress

subclass of Gtk.Bin

PropertyTypeDescription
start-atnumberNumber between 0 and 1, e.g 0.75 is the top
end-atnumberNumber between 0 and 1
invertedboolean
roundedbooleanWether the progress bar should have rounded ends
valuenumberNumber between 0 and 1
const progress = Widget.CircularProgress({
css: 'min-width: 50px;' // its size is min(min-height, min-width)
+ 'min-height: 50px;'
+ 'font-size: 6px;' // to set its thickness set font-size on it
+ 'margin: 4px;' // you can set margin on it
+ 'background-color: #131313;' // set its bg color
+ 'color: aqua;', // set its fg color
rounded: false,
inverted: false,
startAt: 0.75,
value: battery.bind('percent').as(p => p / 100),
child: Widget.Icon({
icon: battery.bind('icon-name'),
}),
})

ColorButton

subclass of Gtk.ColorButton

PropertyType
on-color-set() => void
const colorbutton = Widget.ColorButton({
onColorSet: ({ rgba: { red, green, blue, alpha } }) => {
print(`rgba(${red * 255}, ${green * 255}, ${blue * 255}, ${alpha})`)
},
})

DrawingArea

subclass of Gtk.DrawingArea

PropertyType
draw-fn(cr: Cairo.Context, width: number, height: number) => void
const drawingarea = Widget.DrawingArea({
widthRequest: 50,
heightRequest: 50,
drawFn: (self, cr, w, h) => {
const center = {
x: w / 2,
y: h / 2,
};
cr.setSourceRGBA(1, 1, 1, 1)
cr.setLineWidth(8)
cr.arc(center.x, center.y, 2, 0, Math.PI * 2)
cr.stroke()
},
})

Entry

subclass of Gtk.Entry

PropertyType
on-change() => void
on-accept() => void
const entry = Widget.Entry({
placeholder_text: 'type here',
text: 'initial text',
visibility: true, // set to false for passwords
onAccept: ({ text }) => print(text),
})

EventBox

subclass of Gtk.EventBox

PropertyType
childWidget
on-primary-click(event: Gdk.Event) => boolean
on-secondary-click(event: Gdk.Event) => boolean
on-middle-click(event: Gdk.Event) => boolean
on-primary-click-release(event: Gdk.Event) => boolean
on-secondary-click-release(event: Gdk.Event) => boolean
on-middle-click-release(event: Gdk.Event) => boolean
on-hover(event: Gdk.Event) => boolean
on-hover-lost(event: Gdk.Event) => boolean
on-scroll-up(event: Gdk.Event) => boolean
on-scroll-down(event: Gdk.Event) => boolean

FileChooserButton

subclass of Gtk.FileChooserButton

PropertyTypeDescription
on-file-set() => void
uri() => voidconvenience getter for get_uri
uris() => voidconvenience getter for get_uris
const fbutton = Widget.FileChooserButton({
onFileSet: ({ uri }) => {
print(uri)
},
})

Fixed

subclass of Gtk.Fixed

const fixed = Widget.Fixed({
setup(self) {
self.put(Widget.Label('hello'), 0, 0)
self.put(Widget.Label('hello'), 50, 50)
},
})

FlowBox

subclass of Gtk.FlowBox

const flowbox = Widget.FlowBox({
setup(self) {
self.add(Widget.Label('hello'))
},
})

FontButton

subclass of Gtk.FontButton

PropertyTypeDescription
on-font-set() => void
const fontbutton = Widget.FontButton({
onFontSet: ({ font }) => {
print(font)
},
})

Icon

subclass of Gtk.Image

PropertyTypeDescription
iconstringName of an icon or path to a file
sizenumberForced size
Widget.Icon({ icon: 'dialog-information-symbolic' })
// if you only want an icon, it can be shortened like this
Widget.Icon('dialog-information-symbolic')
// if you don't set a size, it will be computed from css font-size
Widget.Icon({
icon: 'dialog-information-symbolic',
css: 'font-size: 30px',
})
// NOTE:
// setting the icon dynamically has a flicker currently
// to fix it, use a forced size
Widget.Icon({
icon: 'dialog-information-symbolic',
size: 30,
})

Label

subclass of Gtk.Label

PropertyTypeDescription
justificationstringValid values are "left", "center", "right", "fill". Same as justify but represented as a string instead of enum.
truncatestringValid values are "none", "start", "middle", "end". Same as ellipsize but represented as a string instead of enum.
const label = Widget.Label({
label: 'some text to show',
justification: 'left',
truncate: 'end',
xalign: 0,
maxWidthChars: 24,
wrap: true,
useMarkup: true,
})
// shorthand for { label: 'hello' }
Widget.Label('hello')

LevelBar

subclass of Gtk.LevelBar

PropertyTypeDescription
bar-modestringValid values are "continuous", "discrete". Same as mode but represented as a string instead of enum.
verticalboolsetting vertical: true is the same as orientation: 1
const continuous = Widget.LevelBar({
widthRequest: 100,
value: battery.bind("percent").as(p => p / 100),
})
const discrete = Widget.LevelBar({
widthRequest: 100,
bar_mode: "discrete",
max_value: 10,
value: battery.bind("percent").as(p => p / 10),
})

ListBox

subclass of Gtk.ListBox

const listbox = Widget.ListBox({
setup(self) {
self.add(Widget.Label('hello'))
},
})

subclass of Gtk.Menu

PropertyType
childrenMenuItem[]
on-popup(flipped_rect: void, final_rect: void, flipped_x: boolean, flipped_y: boolean) => void
on-move-scroll(scroll_type: Gtk.ScrollType) => void
function RightClickMenu() {
const menu = Widget.Menu({
children: [
Widget.MenuItem({
child: Widget.Label('hello'),
}),
],
})
return Widget.Button({
on_primary_click: (_, event) => {
menu.popup_at_pointer(event)
},
})
}

subclass of Gtk.MenuBar

const menubar = Widget.MenuBar({
setup: self => {
self.append(Widget.Mene())
}
})

subclass of Gtk.MenuItem

PropertyType
childWidget
on-activate() => boolean
on-select() => boolean
on-deselect() => boolean
const menu = Widget.Menu({
children: [
Widget.MenuItem({
child: Widget.Label('hello'),
onActivate: () => {
print('clicked')
}
}),
],
})

Overlay

subclass of Gtk.Overlay Takes the size of its first child, then places subsequent children on top of each other and won’t render them outside the container.

PropertyTypeDescription
childWidgetChild which will determine the size of the overlay
overlaysWidget[]Overlayed children
pass-throughbooleanWhether the overlay childs should pass the input through

ProgressBar

subclass of Gtk.ProgressBar

PropertyTypeDescription
verticalboolSetting vertical: true is the same as orientation: 1
valuenumberSame as ProgressBar.fraction
const progressbar = Widget.ProgressBar({
value: battery.bind("percent").as(p => p / 100),
})

Revealer

subclass of Gtk.Revealer

PropertyTypeDescription
childWidget
transitionstringValid values are "none", "crossfade", "slide_left", "slide_right", "slide_down", "slide_up". This is transitionType represented as a string instead of enum.
const revealer = Widget.Revealer({
revealChild: false,
transitionDuration: 1000,
transition: 'slide_right',
child: Widget.Label('hello!'),
setup: self => self.poll(2000, () => {
self.reveal_child = !self.reveal_child;
}),
})

Scrollable

subclass of Gtk.ScrolledWindow

PropertyTypeDescription
childWidget
hscrollstringValid values are "always, "automatic", "external", "never".
vscrollstringValid values are "always, "automatic", "external", "never".
const scrollable = Widget.Scrollable({
hscroll: 'always',
vscroll: 'never',
style: 'min-width: 20px;',
child: Widget.Label('Lorem ipsum dolor sit amet, ' +
'officia excepteur ex fugiat reprehenderit enim ' +
'labore culpa sint ad nisi Lorem pariatur mollit'),
})

Separator

subclass of Gtk.Separator

PropertyTypeDescription
verticalboolSetting vertical: true is the same as orientation: 1
const separator = Widget.Separator({
vertical: false,
})

Slider

subclass of Gtk.Scale

PropertyTypeDescription
verticalboolSetting vertical: true is the same as orientation: 1
valuenumber
minnumber
maxnumber
markstuple or numberwhere tuple is [number, string?, Position?], Position is "top", "left, "right, "bottom"
on-change(event: Gdk.Event) => void
Widget.Slider({
onChange: ({ value }) => print(value),
vertical: true,
value: 0,
min: 0,
max: 1,
marks: [
1,
2,
[3, 'label'],
[4, 'label', 'bottom'],
],
})

SpinButton

subclass of Gtk.SpinButton

PropertyType
on-value-changed() => void
range[min: number, max: number]
incements[step: number, page: number]
const spinbutton = Widget.SpinButton({
range: [0, 100],
incements: [1, 5],
onValueChanged: ({ value }) => {
print(value)
},
})

Spinner

subclass of Gtk.Spinner spinning icon showing that something is loading

const spinner = Widget.Spinner()

Stack

subclass of Gtk.Stack

PropertyTypeDescription
children{ [string]: Widget }name, Widget key-value pairs
shownstringName of the widget to show. This can’t be set on construction, instead the first given widget will be shown.
transitionstringtransitionType represented as a string. Valid values are none, crossfade, slide_right, slide_left, slide_up, slide_down, slide_left_right, slide_up_down, over_up, over_down, over_left, over_right, under_up, under_down, under_left, under_right, over_up_down, over_down_up, over_left_right, over_right_left
const stack = Widget.Stack({
children: {
'child1': Widget.Label('first child'),
'child2': Widget.Label('second child'),
},
shown: 'child2',
})

Switch

subclass of Gtk.Switch

PropertyType
on-activate() => void
const switch = Widget.Switch({
onActivate: ({ active }) => print(active),
})

ToggleButton

subclass of Gtk.ToggleButton

PropertyType
on-toggled() => void
const togglebutton = Widget.ToggleButton({
onToggled: ({ active }) => print(active),
})