~muktupavels/metacity/adwaita-icon-theme-lp-1414613

« back to all changes in this revision

Viewing changes to doc/creating_themes/C/index.docbook

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2012-09-06 14:48:07 UTC
  • mto: (2.5.2 sid) (1.4.2)
  • mto: This revision was merged to the branch mainline in revision 124.
  • Revision ID: package-import@ubuntu.com-20120906144807-qimlkq3mp118c9vj
Tags: upstream-2.34.8
ImportĀ upstreamĀ versionĀ 2.34.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0"?>
 
2
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 
 
3
  "http://docbook.org/docbook/xml/4.5/docbookx.dtd" [
 
4
]>
 
5
 
 
6
<book id="index">
 
7
 
 
8
  <bookinfo>
 
9
 
 
10
    <title>Understanding Metacity Themes</title>
 
11
 
 
12
    <authorgroup>
 
13
      <author>
 
14
        <firstname>Thomas</firstname>
 
15
        <surname>Thurman</surname>
 
16
      </author>
 
17
    </authorgroup>
 
18
 
 
19
    <abstract>
 
20
 
 
21
      <para>
 
22
        We very much appreciate any reports of inaccuracies or other errors in
 
23
        this document.  Contributions are also most welcome.  Post your
 
24
        suggestions, critiques or addenda to the <ulink
 
25
          url="mailto:tthurman@gnome.org">team</ulink>.</para>
 
26
 
 
27
    </abstract>
 
28
 
 
29
    <copyright>
 
30
      <year>2008</year>
 
31
      <holder>Thomas Thurman</holder>
 
32
    </copyright>
 
33
 
 
34
    <legalnotice>
 
35
      <para>
 
36
        Permission is granted to copy, distribute and/or modify this document
 
37
        under the terms of the GNU Free Documentation License, Version 1.2
 
38
        or any later version published by the Free Software Foundation;
 
39
        with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 
40
        You may obtain a copy of the GNU Free Documentation License from the Free Software Foundation by visiting their Web site or by writing to: Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
41
      </para>
 
42
    </legalnotice>
 
43
 
 
44
  </bookinfo>
 
45
 
 
46
<chapter id="sec-introduction">
 
47
<title>Introduction</title>
 
48
 
 
49
<para>This is an article about how to theme Metacity.  It is a work in progress, and I have had to dig deeply to find some answers; I may well have made mistakes and I welcome corrections and suggestions.</para>
 
50
<para>GNOME lets you theme a bunch of different things, but we're only talking about <literal>window border</literal> themes here, which some people call Metacity themes; <ulink url="http://en.wikipedia.org/wiki/Metacity#Themes">Wikipedia begins a sentence</ulink> with &quot;Despite the incomplete state of Metacity theme development documentation&quot;, and though there <emphasis>is</emphasis> <ulink url="http://svn.gnome.org/viewvc/metacity/trunk/doc/theme-format.txt?view=markup">documentation in the source</ulink>, apparently not many people find it, and it's written more for programmers than theme designers.  Glynn Foster also wrote <ulink url="http://developer.gnome.org/doc/tutorials/metacity/metacity-themes.html">a very good introduction to Metacity themes</ulink> (<ulink url="http://home.arcor.de/rybaczyk/documents/tutorials/metacity/metacity-themes.de.html">[de]</ulink>) six years ago, but things have changed a little since then.  <ulink url="http://lists.freedesktop.org/archives/compiz/2006-September/000445.html">Metacity themes can also be used by Compiz</ulink>, and perhaps by other window managers for all I know.</para>
 
51
 
 
52
<para>So, a Metacity theme is a set of instructions about how to &quot;decorate&quot; (draw the borders around) a window.  Presumably you don't want to style all windows identically, so the format lets you specify details for different kinds of window:</para>
 
53
 
 
54
<para>
 
55
<variablelist>
 
56
  <varlistentry>
 
57
    <term>state:</term><listitem><para>Every window must be in exactly one of these states: <literal>normal</literal>, <literal>dialog</literal>, <literal>modal dialog</literal> (i.e. a dialogue which means you can't interact with the rest of the program while it's up), <literal>menu</literal> (torn off from the main application, not that people do that much these days), <literal>utility</literal> (that is, palettes and toolboxes and things), and <literal>border</literal>.  X also allows a window to explicitly ask to be undecorated, but of course we don't provide for those in a list of decoration instructions.</para></listitem>
 
58
  </varlistentry>
 
59
  <varlistentry>
 
60
    <term>focused</term><listitem><para>Every window is either the active window (which X people call &quot;focused&quot;), or it isn't.</para></listitem>
 
61
  </varlistentry>
 
62
  <varlistentry>
 
63
    <term>maximized</term><listitem><para>Every window is either (fully) maximised (horizontal and vertical only don't count), or it isn't.</para></listitem>
 
64
  </varlistentry>
 
65
  <varlistentry>
 
66
    <term>shaded</term><listitem><para>Every window is either rolled up to show just its titlebar (which techies call &quot;shaded&quot; for some reason I can't fathom), or it isn't.</para></listitem>
 
67
  </varlistentry>
 
68
</variablelist>
 
69
</para>
 
70
 
 
71
<para>
 
72
<itemizedlist>
 
73
<listitem><para><emphasis>If a window is not fully maximised and not shaded,</emphasis> it either allows horizontal resizing, or it doesn't.</para></listitem>
 
74
<listitem><para><emphasis>If a window is not fully maximised and not shaded,</emphasis> it either allows vertical resizing, or it doesn't.</para></listitem>
 
75
</itemizedlist>
 
76
</para>
 
77
 
 
78
</chapter>
 
79
 
 
80
<chapter>
 
81
<title>What's in the file</title>
 
82
 
 
83
<para>The files must be called either</para>
 
84
 
 
85
<para>
 
86
<itemizedlist>
 
87
<listitem><para>~/.themes/<varname>N</varname>/metacity-1/metacity-theme-<varname>V</varname>.xml 
 
88
for a theme used only by you, or</para></listitem>
 
89
<listitem><para>/usr/share/themes/<varname>N</varname>/metacity-1/metacity-theme-<varname>V</varname>.xml 
 
90
for a theme installed for all users.</para></listitem>
 
91
</itemizedlist>
 
92
</para>
 
93
 
 
94
<para>where <varname>N</varname> is the name of the theme and <varname>V</varname> is the version of the format.  Version 2, <ulink url="http://svn.gnome.org/viewvc/metacity?view=revision&amp;revision=2973">introduced in October 2006</ulink>, adds a few extra features, but it's rarely used.  Version 1 is the original format.  The formats are fixed once they're stable for both backwards and forwards compatibility; <ulink url="http://bugzilla.gnome.org/show_bug.cgi?id=482165">new features</ulink> can't be added without introducing a new version number, which is why improvements come out rarely and in large clumps.  <literal>metacity-1</literal> in the names is a fossil and doesn't mean version 1 of anything.</para>
 
95
 
 
96
<para>The metacity-theme-V.xml files are <ulink url="http://blogs.gnome.org/tthurman/2008/02/14/gmarkup/">GMarkup files</ulink>, which are very similar to XML.  For now, you actually have to write these in a text editor or something; you can either start with a blank page, or modify a theme someone else has made.  (I am thinking of writing a general theme editor program, but that'll have to wait until I've reduced Metacity's open bug queue a little.)  If you want to see a fully-fledged one, you can look at <ulink url="http://svn.gnome.org/viewvc/metacity/trunk/src/themes/Atlanta/metacity-theme-1.xml?view=markup">the current version of &quot;Atlanta&quot;</ulink>, one of the simplest themes, but even that is quite complicated-looking at first.</para>
 
97
<para>So, let's talk about what actually goes inside the files.  As in any XML file, &lt;!-<!-- x -->- &#8230; <!-- x -->&gt; are comments.  At its most basic, it would go:</para>
 
98
 
 
99
<para>
 
100
<programlisting>
 
101
&lt;metacity_theme&gt;
 
102
&lt;!-<!-- x -->- Helper stuff: -<!-- x -->-&gt;
 
103
&lt;info &#8230;&gt; &lt;!-<!-- x -->- to be explained -<!-- x -->-&gt;
 
104
&lt;constant &#8230;&gt; &lt;!-<!-- x -->- maybe; to be explained -<!-- x -->-&gt;
 
105
 
 
106
&lt;draw_ops &#8230;&gt; &lt;!-<!-- x -->- maybe; to be explained -<!-- x -->-&gt;
 
107
 
 
108
&lt;!-<!-- x -->- Things we build the top level onto: -<!-- x -->-&gt;
 
109
&lt;frame_geometry &#8230;&gt; &lt;!-<!-- x -->- to be explained -<!-- x -->-&gt;
 
110
 
 
111
&lt;frame_style &#8230;&gt; &lt;!-<!-- x -->- to be explained -<!-- x -->-&gt;
 
112
&lt;frame_style_set &#8230;&gt; &lt;!-<!-- x -->- to be explained -<!-- x -->-&gt;
 
113
 
 
114
&lt;!-<!-- x -->- And the top level: -<!-- x -->-&gt;
 
115
 
 
116
&lt;window type=&quot;normal&quot; style_set=&quot;&#8230;&quot; /&gt;
 
117
&lt;window type=&quot;dialog&quot; style_set=&quot;&#8230;&quot; /&gt;
 
118
&lt;window type=&quot;modal_dialog&quot; style_set=&quot;&#8230;&quot; /&gt;
 
119
 
 
120
&lt;window type=&quot;menu&quot; style_set=&quot;&#8230;&quot; /&gt;
 
121
&lt;window type=&quot;utility&quot; style_set=&quot;&#8230;&quot; /&gt;
 
122
&lt;window type=&quot;border&quot; style_set=&quot;&#8230;&quot; /&gt;
 
123
 
 
124
&lt;/metacity_theme&gt;
 
125
</programlisting>
 
126
</para>
 
127
 
 
128
</chapter>
 
129
 
 
130
<chapter>
 
131
<title>Matching windows</title>
 
132
 
 
133
<para>
 
134
<variablelist>
 
135
  <varlistentry>
 
136
    <term>window</term><listitem><para>You see that at the top level we have a list of &lt;window&gt; tags, one for each window state we discussed above.  The style_set argument of each of these gives the name of a frame_style_set.</para></listitem>
 
137
  </varlistentry>
 
138
  <varlistentry>
 
139
    <term>frame_style_set:</term><listitem><para>tells Metacity how to draw windows according to whether they're focused or not, maximised or not, shaded or not, and allowing resizing vertically, horizontally, both, or neither.  It looks like this:</para></listitem>
 
140
  </varlistentry>
 
141
</variablelist>
 
142
</para>
 
143
 
 
144
<para>
 
145
<programlisting>
 
146
&lt;frame_style_set&gt;
 
147
&lt;frame focus=&quot;F&quot; state=&quot;S&quot; resize=&quot;R&quot; style=&quot;N&quot;/&gt;
 
148
&lt;frame&#8230; /&gt;
 
149
 
 
150
&#8230;
 
151
&lt;/frame_style_set&gt;
 
152
</programlisting>
 
153
</para>
 
154
 
 
155
<para>where:</para>
 
156
 
 
157
<para>
 
158
<variablelist>
 
159
  <varlistentry>
 
160
    <term>F</term><listitem><para>is yes for focused, no for unfocused.</para></listitem>
 
161
  </varlistentry>
 
162
  <varlistentry>
 
163
    <term>S</term><listitem><para>combines the shaded and maximized flags: normal, maximized, shaded, or maximized_and_shaded.</para></listitem>
 
164
  </varlistentry>
 
165
  <varlistentry>
 
166
    <term>R</term><listitem><para>represents resize permissions that the window gives us: none, vertical, horizontal, or both.  Frame settings for maximised windows, which can't be resized, don't have this attribute.</para></listitem>
 
167
  </varlistentry>
 
168
</variablelist>
 
169
</para>
 
170
 
 
171
<para>
 
172
<varname>N</varname> is the name of a <literal>frame_style</literal> to apply to a window which has these attributes.</para>
 
173
 
 
174
<para>A <literal>frame_style_set</literal> tag may also have a &quot;parent&quot; tag, which should be the name of another <literal>frame_style_set</literal>. This means that if Metacity wants to know about a kind of window which that <literal>frame_style_set</literal> doesn't describe, it should look in the parent.  Most of the more complicated tags in Metacity theme files also have a &quot;parent&quot; attribute which work the same way.  This is particularly useful because, taken together, all the <literal>frame_style_set</literal>s in a theme file must be capable of matching every possible kind of window; if a window turns up that they can't match, there will be an error at runtime.</para>
 
175
 
 
176
<para>Let's recap what we've seen so far. The combination of a <literal>window</literal>, which matches a window's state (normal, dialog, and so forth), with an entry in the corresponding <literal>frame_style_set</literal>, which matches its focus, shadedness, maximisedness, and resize permissions where relevant, will allow you to make a list of rules to match any window against.  The next piece of this puzzle lets you specify what Metacity should do with such windows once it's matched them.</para>
 
177
 
 
178
</chapter>
 
179
 
 
180
<chapter>
 
181
<title>Actually drawing stuff</title>
 
182
 
 
183
<para><literal>frame_style:</literal> This is probably the most complicated part of the whole system. A <literal>frame_style</literal> a series of <emphasis><literal>piece</literal></emphasis>s and <emphasis><literal>button</literal></emphasis>s.  It looks like this:</para>
 
184
 
 
185
<para>
 
186
<programlisting>
 
187
&lt;frame_style name=&quot;&#8230;&quot; geometry=&quot;G&quot;&gt;
 
188
&lt;piece position=&quot;P&quot;&gt;
 
189
&lt;draw_ops&gt;
 
190
&lt;/draw_ops&gt;
 
191
&lt;/piece&gt;
 
192
&#8230;
 
193
&lt;button function=&quot;F&quot; state=&quot;S&quot; draw_ops=&quot;D&quot;/&gt;
 
194
 
 
195
&lt;draw_ops&gt;
 
196
&lt;/draw_ops&gt;
 
197
&lt;/button&gt;
 
198
&#8230;
 
199
&lt;/frame_style&gt;
 
200
</programlisting>
 
201
</para>
 
202
 
 
203
<para>The <literal>pieces</literal> are pieces of the window frame.  When Metacity draws a window frame, it renders its various pieces always in the same order.  The bolded parts are all the possible values of P:</para>
 
204
 
 
205
<para>
 
206
<itemizedlist>
 
207
<listitem><para>the <literal>entire_background</literal>, covering the whole frame</para></listitem>
 
208
 
 
209
<listitem><para>the <literal>titlebar</literal>, covering the entire background of the titlebar</para></listitem>
 
210
<listitem><para>the <literal>titlebar_middle</literal>, the part of the titlebar that doesn't touch its edges</para></listitem>
 
211
<listitem><para>the <literal>left_titlebar_edge</literal>, <literal>right_titlebar_edge</literal>, <literal>top_titlebar_edge</literal>, and <literal>bottom_titlebar_edge</literal></para></listitem>
 
212
 
 
213
<listitem><para>the <literal>title</literal>, just exactly that area which is covered by the text on the titlebar</para></listitem>
 
214
<listitem><para>the <literal>left_edge</literal>, <literal>right_edge</literal>, and <literal>bottom_edge</literal> of the frame (yes, there is no top_edge: it's identical to top_titlebar_edge, isn't it?)</para></listitem>
 
215
<listitem><para>the <literal>overlay</literal>, which covers everything&#8211; the same as entire_background, but done last instead of first.</para></listitem>
 
216
</itemizedlist>
 
217
</para>
 
218
 
 
219
<para><emphasis>What</emphasis> Metacity draws in these pieces is decided by the theme.  If a <literal>frame_style</literal> or its parents don't specify a particular piece, nothing will be drawn for that piece.  You have two ways to specify what to draw: one is that the <literal>piece</literal> tag can have a <literal>draw_ops</literal> tag inside it which lists a sequence of drawing operations in Metacity's custom format.  <ulink url="http://bugzilla.gnome.org/show_bug.cgi?id=107012">You might ask why we don't use SVG</ulink>; one answer is that SVG support wasn't very strong when this format was designed, and another answer is that these days you can use SVG all you like; just include it as an image and Metacity will know what to do.</para>
 
220
 
 
221
<para>An alternative to including a draw_ops tag inside a piece tag is to add a draw_ops attribute to the piece tag.  Then you can add a draw_ops tag at top level (inside the metacity_theme tag) with a name attribute, and Metacity will use that.  This is useful if you use similar draw_ops over and over.</para>
 
222
<para>I'm not going to document draw_ops at present, because this is already very long.  I will write it up later and link it from here.</para>
 
223
<para>The <literal>button</literal> tag tells Metacity how, but not where, to draw buttons.  Buttons are drawn after all the pieces are finished, and the way to draw them is also given using draw_ops.  You ought to provide buttons for all the possible kinds of button; if you don't give one it won't be drawn, which is unfortunate for the user who wants to use it:</para>
 
224
 
 
225
<para>
 
226
<itemizedlist>
 
227
<listitem><para><literal>left_left_background</literal>, <literal>left_middle_background</literal>, and <literal>left_right_background</literal> don't represent buttons as such, but the background behind them, assuming there can be at most three buttons on the left.  These days there can be more, so the extra ones also use left_middle_background.</para></listitem>
 
228
 
 
229
<listitem><para><literal>right_left_background</literal>, <literal>right_middle_background</literal>, and <literal>right_right_background</literal> similarly.</para></listitem>
 
230
<listitem><para><literal>close</literal>, <literal>minimize</literal>, <literal>maximize</literal> are the obvious original three buttons.</para></listitem>
 
231
<listitem><para><literal>menu</literal> is the menu button you can click to get a list of actions you can perform on the window.</para></listitem>
 
232
 
 
233
<listitem><para><literal>shade</literal>, <literal>above</literal>, <literal>stick</literal> are similar to the original buttons but only allowed in version 2</para></listitem>
 
234
<listitem><para><literal>unshade</literal>, <literal>unabove</literal>, <literal>unstick</literal> are the toggled versions of these buttons.  Again, version 2 only.</para></listitem>
 
235
 
 
236
</itemizedlist>
 
237
</para>
 
238
 
 
239
<para>The reason there are toggled versions of shade, above, and stick, and not maximize, is that by the time you get this far you've probably already decided whether you're drawing a maximised window.  So if you <emphasis>are</emphasis> drawing a maximised window, you can make the button called &quot;maximize&quot; look how you want the restore button to be; otherwise, make it look like you want the maximise button to be.</para>
 
240
<para>For each button tag you should also set a &quot;state&quot; attribute; this time the state is either <literal>normal</literal> (the way you see it most of the time), <literal>pressed</literal>, or <literal>prelight</literal> (this makes the buttons subtly light up when you hover over them).  You only really need &quot;normal&quot;, but the others are good to have too.</para>
 
241
 
 
242
<para>The &quot;geometry&quot; attribute of a <literal>frame_style</literal> tag is the name of a&#8230;</para>
 
243
 
 
244
</chapter>
 
245
 
 
246
<chapter>
 
247
<title>Geometry</title>
 
248
 
 
249
<para>The <literal>geometry</literal> tag defines the sizes of things around the window.  It is important, but not easy to explain, and again this file has gone on too long.  I'll write it up later.</para>
 
250
 
 
251
</chapter>
 
252
 
 
253
<chapter>
 
254
<title>Other things which lie around a file</title>
 
255
 
 
256
<para>The most important other thing in a theme file is the metadata held in the <literal>info</literal> tag.  This contains a set of tags each of which contains some text explaining something about the theme itself, in a sort of <ulink url="http://en.wikipedia.org/wiki/Dublin_Core">Dublin Core</ulink> sort of way.  (Next time around, we should probably use the actual Dublin Core.)  The tags are <literal>name</literal>, <literal>author</literal>, <literal>copyright</literal>, <literal>date</literal>, and <literal>description</literal>.</para>
 
257
 
 
258
<para>Version 1 of the format had a <literal>menu_icon</literal> tag at top level, which let themes specify the icons beside options in the menu you get from the menu icon.  This has become redundant; the icons are taken from the icon theme!  The tag can still be used in all formats, but does nothing and is deprecated.</para>
 
259
<para>Version 2 of the format has a <literal>fallback</literal> tag at top level, which let the theme specify what icon a window should be considered to have if it doesn't provide an icon of its own.  This should also be taken from the icon theme, <ulink url="http://bugzilla.gnome.org/show_bug.cgi?id=524343">if anyone fancies fixing it</ulink>, and the tag should also then be deprecated.  It shouldn't be hard.</para>
 
260
 
 
261
</chapter>
 
262
 
 
263
<chapter>
 
264
<title>When you're working on a theme</title>
 
265
 
 
266
<para>When you're editing a theme, you can view it without using it on the whole desktop using
 
267
<command>metacity-theme-viewer YourThemeName</command></para>
 
268
<para>and view it on the whole desktop using
 
269
<command>gsettings set org.gnome.desktop.wm.preferences theme YourThemeName</command></para>
 
270
 
 
271
<para>Whenever you change the selected theme in GSettings, Metacity will load the newly-chosen theme.  This is how control-center does it.  But when you change a theme, as you're working on it, you might want to ask Metacity to reload the theme which is currently used on the whole desktop to reflect your changes.  You can do this using the little-known <command>metacity-message</command> program, with the command <literal>metacity-message reload-theme</literal>.  This works by sending the ClientMessage <literal>_METACITY_RELOAD_THEME_MESSAGE</literal> to the root window, in case you're interested.</para>
 
272
 
 
273
<para>Once you're done with your theme, consider submitting it to <ulink url="http://art.gnome.org/themes/metacity/">the art.gnome.org site</ulink>, or <ulink url="http://www.gnome-look.org/index.php?xcontentmode=101">the gnome-look site</ulink>.</para>
 
274
 
 
275
</chapter>
 
276
 
 
277
<chapter>
 
278
<title>The future</title>
 
279
 
 
280
<para>Please feel free to link to this so people don't have to keep asking the basic questions and can start asking the deeper ones.  One of the important deeper ones is: where should we go in the future?  Since this format is becoming something of a de facto standard between window managers, should we set up some kind of freedesktop.org standards discussion?  Would it be useful to spin off Metacity's theme parsing code into a separate, LGPL-licensed library so that other applications could use it more easily?</para>
 
281
<para>What would a version 3 of this format look like?  Could we simplify the window / frame_style_set system? (I can imagine abolishing both, and being able to write <literal>&lt;frame_style for=&quot;normal+unfocused+maximized&quot;&gt;&#8230;</literal> and having Metacity assume it applied to all resize permissions and shadednesses.) Maybe we should try to do everything with SVG we can? Getting more wild and handwavey, is it worth keeping XML-like?  Maybe if other window managers were dealing with the files, .ini-style files would be more universally useful? Or perhaps not.  And then of course we need a decent graphical editor for it.  I have a few ideas, but if anyone fancies jumping in...</para>
 
282
</chapter>
 
283
 
 
284
</book>
 
285
 
 
286