THEMES ====== In golem, a 'theme' is simply a portion of the golemrc file that is included by the main rcfile in ~/.golem/golemrc. The basis of the theme's rc file is the golemrc style block, which contains pixmap declarations and declarations of decoration units, and finally (and most importantly) the grouping of those decoration units. theme rc files are included in user's golemrc file (preferably at the top) with a line like .include "path/to/theme/rc" generally the user's rcfile will include the prepacked distribution themes from .include "themes/ThemeName/rc" and the ones that they have made or downloaded themselves from .include "mythemes/ThemeName/rc" but it's not enforced: a theme may be included from anywhere you want to put it, just specify the path with the .include directive A good way to get familiar with writing a golem theme is to look at the distributed themes and learn how they work. If you understand BNF and/or have written yacc grammers you can look at the file rcfile.y that is part of the source distribution. Either way, you should read the following. A typical golem theme rc file has the following structure: # # forplug includes. these are used to specify an rcfile that should be parsed when # a plugin named "pluginname" is loaded. The rcfile can contain anything a normal # golemrc can contain except loads of other plugins. There is one special block that # may only appear in a forplug file, called 'plugdata'. This block works just like # the inside of a load block (see the file PLUGINS included with this distribution) # and all the parameters made there are merged with the ones defined where the plugin # is loaded. A look at the example themes should clarify this. # forplug "pluginname" "rcfile"; # comment style { # # as a hack, in the current implementation, the font/color for title text is # the same across all dgroups (see below), and is defined here. This # _will_ change in the future. # title_font "-*-courier-*-*-*-*-*-*-*-*-*-*-*-*"; title_color "red"; # # pixmap declations # # IDENTIFIER filename # pixmaps { SOMEPMAP "file.xpm"; FSOMEPMAP "file_foc.xpm"; # the identifier (on the left) must be uppercase and unique PIXMAP2 "pixmap2.xpm"; FPIXMAP2 "pixmap2_foc.xpm"; BUTTON "button.xpm"; FBUTTON "button_foc.xpm"; BPRESSED "pressed.xpm"; # usually a lot more pixmaps are declared than this, of course } # # syntax for declaration of a decoration unit is as such # (as with all of the golemrc stuff, whitespace is nonimportant) # # IDENTIFIER type edge offset lenmod soffset offsetmult lenmult # isshaped isbutton # lclick_action rclick_action # pixmap focusedpixmap [pressedpixmap]; # # type # dec_full the decor unit streches the entire length # of it's edge # dec_near the decor unit is aligned to the lower # numbers of the edge (further up or further # left) # dec_far the decor unit is aligned to the higher # numbers of the edge (further down or to # the right) # # edge dec_top, dec_right, dec_left or dec_bottom # +----------------------------------+ # | top | Note that the top # +---+--------------------------+---+ and bottom edges go over the # | l | | r | corner areas, not the left # | e | | i | and right edges. # | f | | g | # | t | | h | # | | | t | # +---+--------------------------+---+ # | bottom | # +----------------------------------+ # # # offset an integer value that modifies the position # of the unit along it's edge; for instance, # a unit of type dec_near edge dec_top with # offset of 10 will be placed 10 pixels from the # left of the top edge. # # lenmod an integer modifier on the length of the decoration # unit: the base size is the length (width/height depending # on which edge) of the pixmap. Currently the only way # the pixmap is used is by tiling it. # # soffset integer value offset in the secondary direction for the # decoration unit: this allows moving decor units partially # over the client window. # # offsetmult a decimal multiplier on the total length of the # edge that the unit is on, and then added to the # offset of the unit. This allows you to offset a # a unit a distance relative to the size of the edge: # for instance, make it halfway in, or a third in, etc. # # lenmult a decimal multiplier on the total length of the # edge that the unit is on, and then added to the # length of the unit. So you can make a unit that # is half as long as the edge, or so forth. # # isshaped should this window be shaped: for optimization you set # this to false if the pixmap you are using for this window # has no transparency # # isbutton does this behave as a button? i.e., does it perform it's # click actions when the button is released instead of when # it is pressed, and does it use a pressedpixmap. # # lclick_action, # mclick_action, # rclick_action # act_none nothing happens # act_move interactively move the window when clicked # act_resize interactively resize the window when clicked # act_delete send the client WM_DELETE_WINDOW # act_iconify iconify the window # act_zoom zoom the window (maximize) # # pixmap the identifier of a pixmap defined in the pixmaps section # to use for the decoration unit (tiled), when the client it's # on is not focused # # focusedpixmap same as above, but for when the window is focused # # pressedpixmap if isbutton this should be set to the pixmap to use for # when the button is pressed. # # for example, to make something half as long as the edge, but indented by 1/8 of the size # of the edge plus 10 pixels, you would set lenmult to .5, offsetmult to .125, offset to 10 # and lenmod to 0. (you'd use dec_near for type in this case) # # it should be noted that it is sometimes a good idea to overlap adjacent units that use the # multipliers at any value other than 0 by 1 pixel: this will prevent small gaps inbetween # units (1-pixel gaps) when a result from a multiplication is rounded down, etc. # decoration { # # some normal decor units # D1 dec_full dec_top 0 0 0 0 false false act_move act_resize SOMEPMAP FSOMEPMAP; D2 dec_near dec_left 0 0 0 0 true false act_resize act_resize PIXMAP2 FPIXMAP2; # # an example button unit # BUT1 dec_near dec_top 10 0 0 0 true true act_delete act_delete BUTTON FBUTTON PRESSED; # # this is where everything gets tied together. you define a set of # decoration groups (dgroups), and then specify the default dgroup to # use for a few common things, such as for normal windows, and for # transient windows. # # syntax to define a group is: # # DGROUPIDENTIFIER # # the only other thing is a unit may be specified as containing the # window's store_name (title) by putting :title:x:y after it's ident, # where x and y are the offset of the upper left corner for the title # text. the font for the text, and it's color are currently hackishly # global across all dgroups, and is defined in the root of the style # block (above) # groups { DEFAULT D1:title:5:5 D2 BUT1; # # we leave buttons and title off of transients as # an example # TRANSIENTS D1 D2; # # declare default usages of these groups, groups without # default usage definitions here can still be used through # the key_dgroup_switch keybind, or with certain plugins, # such as wmclass_defs. # default DEFAULT; transient TRANSIENTS; internal TRANSIENTS; } } }