summaryrefslogtreecommitdiff
path: root/doc/theme-format.txt
blob: cec702907dab09ddd69afbb271aa36a539596443 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
Themes are in a simple XML-subset format. There are multiple versions
of the theme format, and a given theme can support more than one format.

Version 1:     THEMEDIR/metacity-1/metacity-theme-1.xml
  (original metacity format)
Version 2:     THEMEDIR/metacity-1/metacity-theme-2.xml
Version 3:     THEMEDIR/metacity-1/metacity-theme-3.xml

The subdirectory name is "metacity-1" in all versions.

As you might expect, older versions of marco will not understand
newer theme formats. However, newer versions will use old themes.
Marco will always use the newest theme format it understands that
the X server supports. Some format versions are only supported if you
have the right X server features.

Each format *requires* the corresponding filename. If you put version
2 format features in the metacity-1/metacity-theme-1.xml file, then
marco will get angry.

This document has separate sections for each format version. You may
want to read the document in reverse order, since the base features
are discussed under version 1.

New Features in Theme Format Version 3.3
========================================

Add two additional button background functions - left_single_background and
right_single_background - for button groups with just a single button.

New Features in Theme Format Version 3.2
========================================

A new window type 'attached' is added for modal dialogs which are
attached to their parent window. (When the attach_modal_dialogs preference
is turned on.) If no style is defined for the 'attached' window type,
the 'border' window type will be used instead.

New Features in Theme Format Version 3.1
========================================

Additional predefined variables are added for positioning expressions:

  frame_x_center: the X center of the entire frame, with respect to the
      piece currently being drawn.
  frame_y_center: the Y center of the entire frame, with respect to the
      piece currently being drawn.

The <title/> element now supports an "ellipsize_width" attribute. When
specified, this gives a width at which to ellipsize the title. If not
specified, the title will simply be clipped to the title area.

New Features in Theme Format Version 3
======================================

Format version 3 has exactly one new feature; any element in the file
can now have a version attribute:

  version="[<|<=|=>|>] MAJOR.MINOR"

(< and > should be to be entity escaped as &lt; and &gt;). If this
version check is not met, then the element and its children will be
ignored. This allows having alternate sections of the theme file for
older and newer version of the Metacity theme format.

When placed on the toplevel <metacity_theme> element, an unsatisfied
version check will not just cause the contents of the file to be
ignored, it will also cause the lookup of a theme file to proceed on
and look for an older format 2 or format 1 file. This allows making a
metacity-theme-3.xml file that is only used the format version 3.2 or
newer is supported, and using metacity-theme-1.xml for older window
managers.

New Features in Theme Format Version 2
======================================

The optional attributes rounded_top_left, rounded_top_right,
rounded_bottom_left and rounded_bottom_right on <frame_geometry>
should now be the radius of the corner in pixels. You may still use
the values "false" for 0 and "true" for 5, which means v1 values will
still work just fine.

<frame_geometry> has a new optional attribute, hide_buttons. If this
is true, no buttons will be displayed on the titlebar.

Anywhere you can use a positive integer, you can use an integer constant.

As well as constant integers and reals, you may define constant colours,
thus:
  <constant name="RevoltingPink" value="#FF00FF"/>
  <constant name="Background" value="gtk:bg[NORMAL]"/>

<frame_style> has two new optional attributes, background and alpha.
If you specify alpha, you must specify background. background is a
colour used for the background of the frame. alpha is the transparency
as a real between 0.0 and 1.0. If the current X server does not support
alpha channels, the value is ignored.

The filename attribute of <image> may begin with "theme:". If so, the
rest of the string is the name of a theme icon. The 64x64 version of the
icon is used, except for fallback mini_icons, which use the 16x16 version.
This does not affect ordinary resizing. For example:
  <button function="close" state="normal">
    <draw_ops>
      <include name="active_button"/>
      <image filename="theme:mate-logout" x="2" y="2"
          width="width-4" height="height-4"/>
      <!-- Note: not "theme:mate-logout.png" or similar. -->
    </draw_ops>
  </button>

<menu_icon>s are parsed but ignored.

Fallback icons can be specified using <fallback>. There are two
optional arguments, icon and mini_icon. The values of these arguments
are identical to that of the filename attribute of <image>. Fallback
icons are used when a window does not supply its own icon. If a fallback
icon is not specified with <fallback>, Marco will use a built-in
icon, as in metacity-theme-1.

The <arc> element, as well as the original start_angle and end_angle
attributes, may be given from and to attributes. The values of these
attributes are given in degrees clockwise, with 0 being straight up.
For example:
  <arc from="0.0" to="90.0" filled="true" color="#FF00FF"
      x="0" y="5" width="15" height="15"/>

<frame state="shaded"> may now take an optional resize attribute, with
the same interpretation as the resize attribute on <frame state="normal">.
If this attribute is omitted for state="shaded", it defaults to "both".
(If it is omitted for state="normal", it remains an error.)

In addition to the four <button> functions which are required in
metacity-theme-1, there are six new functions in metacity-theme-2:
shade, unshade, above, unabove, stick and unstick.
      
Overview of Theme Format Version 1
==================================

<?xml version="1.0"?>
<metacity_theme>
<!-- Only one info section is allowed -->
<info>
  <name>Foo</name>
  <author>Foo P. Bar</author>
  <copyright>whoever, 2002</copyright>
  <date>Jan 31 2005</date>
  <description>A sentence about the theme.</description>
</info>

<!-- define a frame geometry to be referenced later -->
<!-- frame_geometry has an optional has_title attribute which 
     determines whether the title text height is included in the 
     height calculation. if not specified, defaults to true.
     It also has an optional text_size="medium" attribute
     (same sizes as with Pango markup, xx-small thru medium thru
     xx-large) 

     Finally it has optional args rounded_top_left=true, 
     rounded_top_right=true, rounded_bottom_left=true,
     rounded_bottom_right=true.

     -->
<frame_geometry name="normal" has_title="true" title_scale="medium">
  <distance name="left_width" value="6"/>
  <distance name="right_width" value="6"/>
  <distance name="bottom_height" value="7"/>
  <distance name="left_titlebar_edge" value="6"/>
  <distance name="right_titlebar_edge" value="6"/>
  <distance name="button_width" value="17"/>
  <distance name="button_height" value="17"/>
  <!-- alternative to button_width button_height distances -->
  <aspect_ratio name="button" value="1.0"/>
  <distance name="title_vertical_pad" value="4"/>
  <border name="title_border" left="3" right="12" top="4" bottom="3"/>
  <border name="button_border" left="0" right="0" top="1" bottom="1"/>
</frame_geometry>

<!-- inheritance is allowed; simply overwrites values from parent -->
<frame_geometry name="borderless" parent="normal">
  <distance name="left_width" value="0"/>
  <distance name="right_width" value="0"/>
  <distance name="bottom_height" value="0"/>
  <distance name="left_titlebar_edge" value="0"/>
  <distance name="right_titlebar_edge" value="0"/>
</frame_geometry>

<!-- define a constant to use in positions/sizes of draw operations;
     constant names must start with a capital letter.
  -->
<constant name="LineOffset" value="3"/>

<!-- define drawing operations to be referenced later; 
     these draw-op lists can also be placed inline. 

     Positions/lengths are given as expressions.
     Operators are: +,-,*,/,%,`max`,`min`
     All operators are infix including `max` and `min`, 
      i.e. "2 `max` 5"
     
     Some variables are predefined, and constants can also 
     be used. Variables are:

       width - width of target area
       height - height of target area
       object_width - natural width of object being drawn
       object_height - natural height of object being drawn
       left_width - distance from left of frame to client window
       right_width - distance from right of frame to client window
       top_height - distance from top of frame to client window
       bottom_height - distance from bottom of frame to client window
       mini_icon_width - width of mini icon for window
       mini_icon_height - height of mini icon
       icon_width - width of large icon
       icon_height - height of large icon
       title_width - width of title text
       title_height - height of title text

    All these are always defined, except object_width/object_height 
    which only exists for <image> right now.

  -->

<draw_ops name="demo_all_ops">
  <line color="#00FF00" x1="LineOffset" y1="0" x2="0" y2="height"/>
  <line color="gtk:fg[NORMAL]" 
        x1="width - 1" y1="0" x2="width - 1" y2="height" 
        width="3" dash_on_length="2" dash_off_length="3"/>
  <rectangle color="blend/gtk:fg[NORMAL]/gtk:bg[NORMAL]/0.7"
             x="0" y="0" width="width - 1" height="height - 1" filled="true"/>
  <arc color="dark gray" x="0" y="0" width="width - 1" height="height - 1" 
       filled="false" start_angle="30" extent_angle="180"/>
  <tint color="orange" alpha="0.5" x="0" y="0" width="width" height="height"/>
 <!-- may be vertical, horizontal, diagonal -->
  <gradient type="diagonal" 
            x="10" y="30" width="width / 3" height="height / 4">
    <!-- any number of colors allowed here. A color can be 
         a color name like "blue" (look at gcolorsel), a hex color
         as in HTML (#FFBB99), or a color from the gtk theme 
         given as "gtk:base[NORMAL]", "gtk:fg[ACTIVE]", etc.
       -->
    <color value="gtk:fg[SELECTED]"/>
    <!-- color obtained by a 0.5 alpha composite of the second color onto the first -->
    <color value="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.5"/>
  </gradient>
  <!-- image has an optional colorize="#color" attribute to give the
       image a certain color -->
  <image filename="foo.png" alpha="0.7"
         x="10" y="30" width="width / 3" height="height / 4"/>
  <gtk_arrow state="normal" shadow="in" arrow="up"
             filled="true"
             x="2" y="2" width="width - 4" height="height - 4"/>
  <gtk_box state="normal" shadow="out"
           x="2" y="2" width="width - 4" height="height - 4"/>
  <gtk_vline state="normal" x="2" y1="0" y2="height"/>
  <!-- window's icon -->
  <icon alpha="0.7"
        x="10" y="30" width="width / 3" height="height / 4"/>
  <!-- window's title -->
  <title color="gtk:text[NORMAL]" x="20" y="30"/>
  <!-- include another draw ops list; has optional x/y/width/height attrs -->
  <include name="some_other_draw_ops"/>
  <!-- tile another draw ops list; has optional
       x/y/width/height/tile_xoffset/tile_yoffset -->
  <tile name="some_other_draw_ops" tile_width="10" tile_height="10"/>
</draw_ops>

<frame_style name="normal" geometry="normal">
  <!-- How to draw each piece of the frame.
       For each piece, a draw_ops can be given inline or referenced 
       by name. If a piece is omitted, then nothing will be drawn 
       for that piece.

       For each piece, the "width" and "height" variables in 
       coordinate expressions refers to the dimensions of the piece, 
       the origin is at the top left of the piece.
  
       So <rectangle x="0" y="0" width="width-1" height="height-1"/>
       will outline a piece.
    -->

  <piece position="entire_background" draw_ops="demo_all_ops"/>
  <piece position="left_titlebar_edge">
    <draw_ops>
      <line color="#00FF00" x1="0" y1="0" x2="0" y2="height"/>
    </draw_ops>
  </piece>

  <!-- The complete list of frame pieces:

       entire_background: whole frame
       titlebar: entire area above the app's window 
       titlebar_middle: area of titlebar_background not considered
                        part of an edge
       left_titlebar_edge: left side of titlebar background
       right_titlebar_edge: right side of titlebar background
       top_titlebar_edge: top side of titlebar background
       bottom_titlebar_edge: bottom side of titlebar background 
       title: the title area (doesn't include buttons)
       left_edge: left edge of the frame
       right_edge: right edge of the frame
       bottom_edge: bottom edge of the frame
       overlay: same area as entire_background, but drawn after 
                drawing all sub-pieces instead of before

   -->

  <!-- For buttons, drawing methods have to be provided for 
       each of three states: 
          normal, pressed, prelight
       and the button function or position must be provided:
          close, maximize, minimize, menu, 
          left_left_background, left_middle_background,
          left_right_background, right_left_background, 
          right_middle_background, right_right_background
       So a working theme needs 3*4 = 12 button declarations
       and a theme may have up to 3*10 = 30 button declarations
       in order to handle button-rearrangement preferences.
 
       (The name "function" for the attribute is from before the 
        background values existed.)
    -->

  <button function="close" state="normal" draw_ops="previously_named"/>
  <button function="menu" state="normal">
    <draw_ops>
      <icon alpha="0.7"
            x="0" y="0" width="object_width" height="object_height"/>
    </draw_ops>
  </button>

</frame_style>

<!-- styles can inherit from each other with the parent="" attribute. 
     In a subclass anything can be re-specified to override 
     the parent style. -->
<frame_style name="focused" parent="normal">
  <piece position="title">
    <draw_ops>
      <rectangle color="gtk:bg[SELECTED]"
                 x="0" y="0" width="width-1" height="height-1"/>
      <title color="gtk:fg[SELECTED]" x="(width - title_width) / 2"
                                      y="(height - title_height) / 2"/>
    </draw_ops>
  </piece>
</frame_style>

<!-- Maps styles to states of frame. 

     Focus: yes (focused), no (not focused)
     Window states: normal, maximized, shaded, maximized_and_shaded
     Window resizability: none, vertical, horizontal, both

     Everything unspecified just does the same as
     unfocused/normal/both.

     only state="normal" needs a resize="" attribute.
 -->
<frame_style_set name="normal">
<frame focus="yes" state="normal" resize="both" style="focused"/>
<frame focus="no" state="normal" resize="both" style="normal"/>
</frame_style_set>

<!-- Each window type needs a style set 
     Types: normal, dialog, modal_dialog, menu, utility, border
  -->
<window type="normal" style_set="normal"/>


<!-- For menu icons, drawing methods are needed for the same 
     four types as the buttons, and GTK states
     (insensitive,prelight,normal,etc.)
  -->

<menu_icon function="close" state="normal" draw_ops="previously_named"/>


</metacity_theme>