GRUB 2 Graphical Menu Theme File Format

Author: Colin D. Bennett <colin@gibibit.com>
Date: 16 August 2008

Introduction

The GRUB graphical menu supports themes that can customize the layout and appearance of the GRUB boot menu. The theme is configured through a plain text file that specifies the layout of the various GUI components (including the boot menu, timeout progress bar, and text messages) as well as the appearance using colors, fonts, and images.

Theme Elements

Colors

Colors can be specified in several ways:

  • HTML-style #RRGGBB or #RGB format, where R, G, and B are hexadecimal digits (e.g., #8899FF,
  • as comma-separated decimal RGB values (e.g., 128, 128, 255), or
  • with SVG 1.0 color names (e.g., cornflowerblue) which must be specified in lowercase.

Fonts

The fonts GRUB uses PFF2 font format bitmap fonts. Fonts are specified with full font names, such as Helvetica Bold 18. Currently there is no provision for a preference list of fonts, or deriving one font from another. Fonts are loaded with the loadfont command in GRUB. To see the list of loaded fonts, execute the lsfonts command. If there are too many fonts to fit on screen, do set pager=1 before executing lsfonts.

Progress Bar

Theme_progress_bar.png

Pixmap-styled progress bar.

Theme_progress_bar_filled.png

Plain progress bar, drawn with solid color.

Progress bars are used to display the remaining time before GRUB boots the default menu entry. To create a progress bar that will display the remaining time before automatic boot, simply create a progress_bar component with the id __timeout__. This indicates to GRUB that the progress bar should be updated as time passes, and it should be made invisible if the countdown to automatic boot is interrupted by the user.

Progress bars may optionally have text displayed on them. This is controlled through the show_text property, which can be set to either true or false to control whether text is displayed. When GRUB is counting down to automatic boot, the text informs the user of the number of seconds remaining.

Circular Progress Indicator

Theme_circular_progress.png

The circular progress indicator functions similarly to the progress bar. When given an id of __timeout__, GRUB updates the circular progress indicator's value to indicate the time remaining. For the circular progress indicator, there are two images used to render it: the center image, and the tick image. The center image is rendered in the center of the component, while the tick image is used to render each mark along the circumference of the indicator.

Labels

Text labels can be placed on the boot screen. The font, color, and horizontal alignment can be specified for labels. If a label is given the id __timeout__, then the text property for that label is also updated with a message informing the user of the number of seconds remaining until automatic boot. This is useful in case you want the text displayed somewhere else instead of directly on the progress bar.

Boot Menu

Theme_boot_menu.png

The boot menu where GRUB displays the menu entries from the grub.cfg file. It is a list of items, where each item has a title and an optional icon. The icon is selected based on the classes specified for the menu entry. If there is a PNG file named myclass.png in the grub/themes/icons directory, it will be displayed for items which have the class myclass. The boot menu can be customized in several ways, such as the font and color used for the menu entry title, and by specifying styled boxes for the menu itself and for the selected item highlight.

Styled Boxes

One of the most important features for customizing the layout is the use of styled boxes. A styled box is composed of 9 rectangular (and potentially empty) regions, which are used to seamlessly draw the styled box on screen:

Box_slice_names.png

The 9 slices that make up a box. The abbreviation below each name is used to identify the image for that slice.

To support any size of box on screen, the center slice and the slices for the top, bottom, and sides are all scaled to the correct size for the component on screen, using the following rules:

  1. The edge slices (north, south, east, and west) are scaled in the direction of the edge they are adjacent to. For instance, the west slice is scaled vertically.
  2. The corner slices (northwest, northeast, southeast, and southwest) are not scaled.
  3. The center slice is scaled to fill the remaining space in the middle.

As an example of how an image might be sliced up, consider the styled box used for a terminal view.

Box_slice_example_terminal.png

An example of the slices (in red) used for a terminal window. This drawing was created and sliced in Inkscape, as the next section explains.

Creating Styled Box Images

The Inkscape scalable vector graphics editor is a very useful tool for creating styled box images. One process that works well for slicing a drawing into the necessary image slices is:

  1. Create or open the drawing you'd like use.
  2. Create a new layer on the top of the layer stack. Make it visible. Select this layer as the current layer.
  3. Draw 9 rectangles on your drawing where you'd like the slices to be. Clear the fill option, and set the stroke to 1 pixel wide solid stroke. The corners of the slices must meet precisely; if it is off by a single pixel, it will probably be evident when the styled box is rendered in the GRUB menu. You should probably go to File | Document Properties | Grids and enable a grid or create a guide (click on one of the rulers next to the drawing and drag over the drawing; release the mouse button to place the guide) to help place the rectangles precisely.
  4. Right click on the center slice rectangle and choose Object Properties. Change the "Id" to slice_c and click Set. Repeat this for the remaining 8 rectangles, giving them Id values of slice_n, slice_ne, slice_e, and so on according to the location.
  5. Save the drawing.
  6. Select all the slice rectangles. With the slice layer selected, you can simply press Ctrl+A to select all rectangles. The status bar should indicate that 9 rectangles are selected.
  7. Click the layer hide icon for the slice layer in the layer palette. The rectangles will remain selected, even though they are hidden.
  8. Choose File | Export Bitmap and check the Batch export 9 selected objects box. Make sure that Hide all except selected is unchecked. click Export. This will create PNG files in the same directory as the drawing, named after the slices. These can now be used for a styled box in a GRUB theme.

Theme File Examples

Winter

# GRUB gfxmenu theme "winter".
# Uses background image from:
# http://www.cyberpunkcafe.com/e107_plugins/autogallery/autogallery.php?show=1.Open%20Source%20Wallpaper
# "without-leaves.png" was called "Without Leafs in Winter.png"
# Designed for 640x480 resolution.

title-text: ""
title-font: "Helvetica Bold 18"
message-font: "Helvetica 8"
title-color: "40, 40, 40"
message-color: "#FFF"
message-bg-color: "0, 166, 183"
desktop-image: "without-leaves.png"
desktop-color: "0, 154, 183"
terminal-box: "terminal_*.png"

+ boot_menu {
   position = (100, 65)
   preferred_size = (440, -1)
   item_font = "Helvetica Bold 14"
   selected_item_font = "Helvetica Bold 14"
   item_color = "0, 0, 0"
   selected_item_color = "203, 251, 255"
   menu_pixmap_style = "menu_*.png"
   selected_item_pixmap_style = "select_*.png"
   icon_width = 44
   icon_height = 44
   item_height = 32
   item_padding = 0
   item_icon_space = 3
   item_spacing = 11

   max_items_shown = 5
   scrollbar = true
   scrollbar_frame = "sb_fr_*.png"
   scrollbar_thumb = "sb_th_*.png"
   scrollbar_width = 15
}

# Informational message bar at the bottom of the screen.
+ vbox {
   position = (10, 440)
   preferred_size = (620, 40)
   + label {
      text="Select an item with the arrow keys and press Enter to boot."
      font="lime 11" color=#000
   }
   + label {
      text="Press:  'c' for command line; 't' to switch to non-graphical menu."
      font="lime 11" color=#000
   }
}

# You can add text at arbitrary locations on the screen.
# The specification within the "+label {...}" block is free-form,
# so you can use as much or as little white space as you like.

+ label {
   position = (170, 50)
   font = "smoothansi 13"
   color = "0,0,128"
   text = "This is the Winter theme ... brought to you by GRUB!"
}

# Show the text alignment supported by labels.
+ vbox {
   position = (220, 347)
   preferred_size = (200, -1)     # A preferred size of -1 means automatic.
   + label { text="Text alignment demo" align="center" font="aqui 11" }
   + label { text="Left" align="left" font="cure 11" }
   + label { text="Center" align="center" font="cure 11" }
   + label { text="Right" align="right" font="cure 11" }
}

+ vbox {
   position = (580, 10)
   + label { text="GNU" font="gelly 11" color="0, 0, 0" }
   + label { text="GRUB" font="aqui 11" color="0, 0, 0" }
   + label { text="boot loader" font="cure 11" color="0, 0, 0" }
}

+ hbox {
   position = (80, 10)
   + label { text="GNU" font="gelly 11" color="0, 0, 0" }
   + label { text="GRUB" font="aqui 11" color="0, 0, 0" }
   + label { text="boot loader" font="cure 11" color="0, 0, 0" }
}

# Demonstration of a compound layout: boxes within boxes.
+ hbox
{
   position = (480, 3)

   + vbox
   {
      # Note: We can't just use 'size' to set the image's size,
      #       since the vbox will resize the component according to its
      #       preferred size, which for images is the native image size.

      + image { file="/boot/grub/themes/icons/ubuntu.png"
                preferred_size = (20, 20) }
      + image { file="/boot/grub/themes/icons/gentoo.png"
                preferred_size = (20, 20) }
   }

   + vbox
   {
      + label { text="GRand" font="cure 11" color=#99F }
      + label { text="Unified" font="cure 11" color=#BBF }
      + label { text="Bootloader" font="cure 11" color=#DDF }
   }
}

# By defining a 'progress_bar' type component with an ID of '__timeout__',
# the progress bar will be used to display the time remaining before an
# the default entry is automatically booted.
+ progress_bar
{
   id = "__timeout__"
   position = (80, 393)
   preferred_size = (500, 24)
   font = "cure 11"
   text_color = #000
   fg_color = #CCF
   bg_color = #66B
   border_color = #006
   show_text = false
}

# Although the progress_bar component is normally used to indicate the
# time remaining, it's also possible to create other components with an ID
# of '__timeout__'.  All components with and ID of 'timeout_bar' will have
# the following properties set based on the timeout value:
#   text, value, start, end, visible.
# In this case, we have set 'show_text=false' on the progress bar, and use
# the following label's 'text' property to display the message.
+ label
{
   id = "__timeout__"
   position = (80, 420)
   preferred_size = (500, 24)
   font = "lime 11"
   color = #117
   align = "center"
}

Theme File Manual

The theme file is a plain text file. Lines that begin with # are ignored and considered comments. (Note: This may not be the case if the previous line ended where a value was expected.)

The theme file contains two types of statements:

  1. Global properties.
  2. Component construction.

Global Properties

Format

Global properties are specified with the simple format:

name1: value1
name2: "value which may contain spaces"
name3: #88F

In this example, name3 is assigned a color value.

Global Property List

title-text
Specifies the text to display at the top center of the screen as a title.
title-font
Defines the font used for the title message at the top of the screen.
title-color
Defines the color of the title message.
message-font
Defines the font used for messages, such as when GRUB is unable to automatically boot an entry.
message-color
Defines the color of the message text.
message-bg-color
Defines the background color of the message text area.
desktop-image
Specifies the image to use as the background. It will be scaled to fit the screen size.
desktop-color
Specifies the color for the background if desktop-image is not specified.
terminal-box

Specifies the file name pattern for the styled box slices used for the command line terminal window. For example,

terminal-box: terminal_*.png

will use the images terminal_c.png as the center area, terminal_n.png as the north (top) edge, terminal_nw.png as the northwest (upper left) corner, and so on. If the image for any slice is not found, it will simply be left empty.

Component Construction

Greater customizability comes is provided by components. A tree of components forms the user interface. Containers are components that can contain other components, and there is always a single root component which is an instance of a canvas container.

Components are created in the theme file by prefixing the type of component with a '+' sign:

+ label { text="GRUB" font="aqui 11" color="#8FF" }

properties of a component are specified as "name = value" (whitespace surrounding tokens is optional and is ignored) where value may be:

  • a single word (e.g., align = center, color = #FF8080),
  • a quoted string (e.g., text = "Hello, World!"), or
  • a tuple (e.g., preferred_size = (120, 80)).

Component List

The following is a list of the components and the properties they support.

label

A label displays a line of text.

Properties:

text
The text to display.
font
The font to use for text display.
color
The color of the text.
align
The horizontal alignment of the text within the component. Options are left, center, and right.
image

A component that displays an image. The image is scaled to fit the component, although the preferred size defaults to the image's original size unless the preferred_size property is explicitly set.

Properties:

file
The full path to the image file to load.
progress_bar

Displays a horizontally oriented progress bar. It can be rendered using simple solid filled rectangles, or using a pair of pixmap styled boxes.

Properties:

fg_color
The foreground color for plain solid color rendering.
bg_color
The background color for plain solid color rendering.
border_color
The border color for plain solid color rendering.
text_color
The text color.
show_text
Boolean value indicating whether or not text should be displayed on the progress bar. If set to false, then no text will be displayed on the bar. If set to any other value, text will be displayed on the bar.
bar_style
The styled box specification for the frame of the progress bar. Example: progress_frame_*.png
highlight_style
The styled box specification for the highlighted region of the progress bar. This box will be used to paint just the highlighted region of the bar, and will be increased in size as the bar nears completion. Example: progress_hl_*.png.
text
The text to display on the progress bar. If the progress bar's ID is set to __timeout__, then GRUB will updated this property with an informative message as the timeout approaches.
value
The progress bar current value. Normally not set manually.
start
The progress bar start value. Normally not set manually.
end
The progress bar end value. Normally not set manually.
circular_progress

Displays a circular progress indicator. The appearance of this component is determined by two images: the center image and the tick image. The center image is generally larger and will be drawn in the center of the component. Around the circumference of a circle within the component, the tick image will be drawn a certain number of times, depending on the properties of the component.

Properties:

center_bitmap
The file name of the image to draw in the center of the component.
tick_bitmap
The file name of the image to draw for the tick marks.
num_ticks
The number of ticks that make up a full circle.
ticks_disappear
Boolean value indicating whether tick marks should progressively appear, or progressively disappear as value approaches end. Specify true or false.
value
The progress indicator current value. Normally not set manually.
start
The progress indicator start value. Normally not set manually.
end
The progress indicator end value. Normally not set manually.
boot_menu

Displays the GRUB boot menu. It allows selecting items and executing them.

Properties:

item_font
The font to use for the menu item titles.
selected_item_font
The font to use for the selected menu item, or inherit (the default) to use item_font for the selected menu item as well.
item_color
The color to use for the menu item titles.
selected_item_color
The color to use for the selected menu item, or inherit (the default) to use item_color for the selected menu item as well.
icon_width
The width of menu item icons. Icons are scaled to the specified size.
icon_height
The height of menu item icons.
item_height
The height of each menu item in pixels.
item_padding
The amount of space in pixels to leave on each side of the menu item contents.
item_icon_space
The space between an item's icon and the title text, in pixels.
item_spacing
The amount of space to leave between menu items, in pixels.
menu_pixmap_style
The image file pattern for the menu frame styled box. Example: menu_*.png (this will use images such as menu_c.png, menu_w.png, menu_nw.png`, etc.)
selected_item_pixmap_style
The image file pattern for the selected item highlight styled box.
scrollbar
Boolean value indicating whether the scroll bar should be drawn if the frame and thumb styled boxes are configured.
scrollbar_frame
The image file pattern for the entire scroll bar. Example: scrollbar_*.png
scrollbar_thumb
The image file pattern for the scroll bar thumb (the part of the scroll bar that moves as scrolling occurs). Example: scrollbar_thumb_*.png
max_items_shown
The maximum number of items to show on the menu. If there are more than max_items_shown items in the menu, the list will scroll to make all items accessible.
canvas
Canvas is a container that allows manual placement of components within it. It does not alter the positions of its child components. It assigns all child components their preferred sizes.
hbox
The hbox container lays out its children from left to right, giving each one its preferred width. The height of each child is set to the maximum of the preferred heights of all children.
vbox
The vbox container lays out its children from top to bottom, giving each one its preferred height. The width of each child is set to the maximum of the preferred widths of all children.

Common properties

The following properties are supported by all components:

preferred_size
The preferred size of the component. The parent container normally uses the preferred size of its children to do the layout. If either the height or the width coordinate of preferred_size is -1, the component uses its own default value for that coordinate. The default preferred size calculate varies by component type. For labels, the actual text size is used to determine the preferred size, while for images, the preferred size is equal to the image's original size.
position
The (x, y) coordinate of the label relative to the upper left corner of its parent container.
id

The identifier for the component. This can be any arbitrary string. The ID can be used by scripts to refer to various components in the GUI component tree. Currently, there is one special ID value that GRUB recognizes:

__timeout__
Any component with this ID will have its text, start, end, value, and visible properties set by GRUB when it is counting down to an automatic boot of the default menu entry.