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.

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.

Screenshots

Internet menu opened

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-2024, 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 to above all others
	;
	_hnd.set_attrs(\
		attribute: ALWAYS_ABOVE, \
		attribute_value: SET_ON)

	; Window border off
	;
	_hnd.set_attrs(\
		attribute: SET_BORDER, \
		attribute_value: SET_OFF)

	; 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-2024, 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-2024, Jani Salonen <salojan@goto10.co>
; All rights reserved.
;

;
; Menu is attached to window where WIDGET_STACK_ID was 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",		item_id,	callback,	flags,	optional_icon
			; ----  -----		-------		--------	-----	-------------
			;
			item "Firefox",		1,		cb_launch,	none,	examples/datafiles/dm_inet_ff.tga
			item "Opera",		2,		cb_launch,	none,	examples/datafiles/dm_inet_op.tga
		}

		menu "Multimedia" {							examples/datafiles/dm_mm.tga
			item "VLC Player",	10,		cb_launch,	none,	examples/datafiles/dm_mm_vlc.tga
		}

		menu "X Tools" {							examples/datafiles/dm_ss.tga
			item "XCalc",		20,		cb_launch,	none,	none
			item "XClock",		21,		cb_launch,	none,	none
			item "XTerm",		22,		cb_launch,	none,	none

			delim

			menu "Backlight" {
				radio "10%",	30,		cb_launch,	none,	none
				radio "20%",	30,		cb_launch,	none,	none
				radio "30%",	30,		cb_launch,	none,	none
				radio "40%",	30,		cb_launch,	none,	none
				radio "50%",	30,		cb_launch,	none,	none
				radio "60%",	30,		cb_launch,	none,	none
				radio "70%",	30,		cb_launch,	none,	none
				radio "80%",	30,		cb_launch,	none,	none
				radio "90%",	30,		cb_launch,	none,	none
				radio "100%",	30,		cb_launch,	none,	none
			}

			delim

			item "XKill",		23,		cb_launch,	none,	none
		}

		menu "Session" {							examples/datafiles/dm_ss.tga
			item "Exit Deskmenu",	40,		cb_exit,	none,	examples/datafiles/dm_ss_exit.tga
		}
	}
}

Copyright © 2024, Jani Salonen <salojan at goto10 piste co>. Piste is finnish word and means dot. All rights reserved.