Deskmenu
Deskmenu is a small desktop app launcher. By default is shows couple of apps and launches them when selected. Written in plain Ano script, no C involved.
Deskmenu demonstrates how to attach menu to widget and external command calling in widget callback function, as well how to set some window attributes, like borderless and keep-above. Deskmenu also makes use of settings system to save some menu item state.
User interface
Menu pops up by pressing middle mouse button, or alternatively keep <ctrl> key pressed while pressing left mouse button.
Compilation
Easiest way to get Deskmenu running is to go to examples directory in package root, and run:
$ ./build.sh gui_deskmenu
build.sh script compiles Ano script, menu and widget definitions to C, copies source files in place and pops up instructions what to do next. Follow them. Check also examples/README for more info.
Preview
;
; This little application pops up a launcher menu.
;
; @ANO_SCRIPT_NAME gui_deskmenu
; @ANO_SCRIPT_VERSION 0.0.6
; @ANO_SCRIPT_DESCRIPTION Simple application launcher menu
;
; @ANO_FLAGS_VAR_NAME_SUBS [x]
; @ANO_FLAGS_VAR_WARN_UNUSED [ ]
;
; Copyright (c) 2016-2025, Jani Salonen <salojan@goto10.co>
; All rights reserved.
;
main {
; Initialize windowing system...
;
gui_enabled {
window_init
; ...and open main window
;
window_open (\
title_name: NULL, \
title_charset: NULL, \
parent_handle: NOPARENT, \
widget_stack_id: 1, \
widget_set: 0, \
window_refresh_divider: PASSIVE_REFRESH, \
position_x: POS_CENTERED, \
position_y: POS_CENTERED, \
size_width: 200, \
size_height: 40, \
cb_main_loop: NULL, \
cb_expose: NULL, \
cb_key_press: NULL, \
cb_key_release: NULL, \
cb_button_press: NULL, \
cb_button_release: NULL, \
cb_client_message: NULL, \
cb_save_yourself: NULL, \
cb_configure_notify: NULL, \
cb_destroy_notify: "cb_destroy", \
cb_motion_notify: NULL, \
cb_map_notify: NULL, \
cb_unmap_notify: NULL, \
cb_open_notify: "cb_open")
}
}
_WINCB_OPEN_ callback cb_open (_hnd) {
; Window is the topmost window
;
_hnd.set_attrs(\
attribute: ALWAYS_ABOVE, \
attribute_value: SET_ON)
; Get borders off
;
_hnd.set_attrs(\
attribute: SET_BORDER, \
attribute_value: SET_OFF)
; Ask for fetching menu settings and saving them back, consumer_name
; is defined in key column in menu definitions table
;
; This is for Backlight -radio group...
;
settings_register (\
consumer_name: "blight", \
consumer_class: SETTINGS_MENU)
; ...and this is for Save settings -check item
;
settings_register (\
consumer_name: "saving", \
consumer_class: SETTINGS_MENU)
; Map window
;
_hnd.map()
}
_WINCB_DESTROY_ callback cb_destroy (_hnd) {
_hnd.destroy()
exit
}
_WIDGETCB_BUTTON_ callback cb_button_press (_hnd, _x, _y, _x_root, _y_root, _state, _button) {
}
_MENUCB_ITEM_ callback cb_exit (_item, _position, _tag, _flag) {
exit
}
_MENUCB_ITEM_ callback cb_launch (_item, _position, _tag, _flag) {
; Internet menu
;
if _tag == 1 : &cb_launch_it ("firefox")
if _tag == 2 : &cb_launch_it ("opera")
; Multimedia menu
;
if _tag == 10 : &cb_launch_it ("vlc")
; X Tools menu
;
if _tag == 20 : &cb_launch_it ("xcalc")
if _tag == 21 : &cb_launch_it ("xclock")
if _tag == 22 : &cb_launch_it ("xterm")
if _tag == 23 : &cb_launch_it ("xkill")
if _tag == 30 : &cb_launch_30 (_flag)
}
function cb_launch_it (_app) {
; Execute the application
;
exec (_app)
}
function cb_launch_30 (_flag) {
; Adjust 0-9 to 10-100
;
mul _flag (10)
add _flag (10)
; Number to string for exec()
;
ntos _flag
exec ("xbacklight", "-set", _flag)
}
;
; Copyright (c) 2016-2025, Jani Salonen <salojan@goto10.co>
; All rights reserved.
;
; @WIDGET_USE_BOUNDING_BOXES no
;
window "1" {
set "0" {
widget "background" {
name "background"
state enable
color "rgb:#000000"
}
widget "block" {
name "launcher"
state enable
position x = 0, y = 0
size width = 200, height = 40
color "rgba:#ffffddff"
border color = rgba:#5aa6bbff, thickness = 2
; This empty callback is needed for menu to pop up
action buttonpress = cb_button_press
}
widget "label" {
name "label"
state enable
position x = 100, y = 4
label "MMB to start", \
charset = UTF-8, size = 12, \
color = rgb:#441111, \
justification = center
}
}
}
;
; Copyright (c) 2016-2025, Jani Salonen <salojan@goto10.co>
; All rights reserved.
;
;
; Menu is attached to window where WIDGET_STACK_ID is set to 1.
;
; container_type "container_id" {
;
window "1" {
widget "launcher" {
;
; menu "menu_name" { optional_icon
; --------- -------------
;
menu "Internet" { examples/datafiles/dm_inet.tga
;
; type "title", id, key, callback, flags, optional_icon
; ---- ----- -- --- -------- ----- -------------
;
item "Firefox", 1, none, cb_launch, none, examples/datafiles/dm_inet_ff.tga
item "Opera", 2, none, cb_launch, none, examples/datafiles/dm_inet_op.tga
}
menu "Multimedia" { examples/datafiles/dm_mm.tga
item "VLC Player", 10, none, cb_launch, none, examples/datafiles/dm_mm_vlc.tga
}
menu "X Tools" { examples/datafiles/dm_ss.tga
item "XCalc", 20, none, cb_launch, none, none
item "XClock", 21, none, cb_launch, none, none
item "XTerm", 22, none, cb_launch, none, none
delim
menu "Backlight" {
radio "10%", 30, blight, cb_launch, none, none
radio "20%", 30, blight, cb_launch, none, none
radio "30%", 30, blight, cb_launch, none, none
radio "40%", 30, blight, cb_launch, none, none
radio "50%", 30, blight, cb_launch, none, none
radio "60%", 30, blight, cb_launch, none, none
radio "70%", 30, blight, cb_launch, none, none
radio "80%", 30, blight, cb_launch, none, none
radio "90%", 30, blight, cb_launch, none, none
radio "100%", 30, blight, cb_launch, none, none
}
delim
item "XKill", 23, none, cb_launch, none, none
}
menu "Session" { examples/datafiles/dm_ss.tga
check "Save settings", 40, saving, none, sync_settings_on_change, \
none
delim
item "Exit Deskmenu", 41, none, cb_exit, none, examples/datafiles/dm_ss_exit.tga
}
}
}
Screenshots
Click to enlarge.
Copyright © 2025, Jani Salonen <salojan at goto10 piste co>. Piste is finnish word and means dot. All rights reserved.
