34551129a36b4a41d36fcd6624ffe02907b24fac
[tilda-gobject.git] / tilda-window.c
1 #include "tilda.h"
2 #include "tilda-window.h"
3 #include "tilda-window-dbus-glue.h"
4
5 static gint
6 tilda_window_find_next_free_terminal_number (TildaWindow *tw)
7 {
8         gint i, j;
9         gboolean found;
10
11         for (i=0; i<INT_MAX; ++i)
12         {
13                 found = FALSE;
14
15                 for (j=0; j<tw->terms->len; ++j)
16                 {
17                         TildaTerminal *tt = g_ptr_array_index (tw->terms, j);
18
19                         if (tt->number == i)
20                         {
21                                 found = TRUE;
22                                 break;
23                         }
24                 }
25
26                 if (!found)
27                         return i;
28         }
29
30         return 0;
31 }
32
33 static gboolean
34 tilda_window_add_term (TildaWindow *tw)
35 {
36         gint number;
37         TildaTerminal *tt;
38
39         number = tilda_window_find_next_free_terminal_number (tw);
40         tt = g_object_new (TILDA_TYPE_TERMINAL,
41                                            "number", number,
42                                            "window-number", tw->number,
43                                            "parent-window", tw,
44                                            NULL);
45         g_ptr_array_add (tw->terms, tt);
46
47         GtkWidget *label = gtk_label_new ("Tilda");
48         gint index = gtk_notebook_prepend_page (GTK_NOTEBOOK(tw->notebook), tt->hbox, label);
49         gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK(tw->notebook), tt->hbox, TRUE, TRUE, GTK_PACK_END);
50         //gtk_notebook_set_current_page (GTK_NOTEBOOK(tw->notebook), index);
51
52         if (gtk_notebook_get_n_pages (GTK_NOTEBOOK(tw->notebook)) > 1)
53                 gtk_notebook_set_show_tabs (GTK_NOTEBOOK(tw->notebook), TRUE);
54
55         return TRUE;
56 }
57
58 /**
59  * Remove the TildaTerminal with the given number from the given
60  * TildaWindow.
61  *
62  * Return: TRUE on success, FALSE otherwise.
63  */
64 gboolean
65 tilda_window_remove_term (TildaWindow *tw, gint terminal_number)
66 {
67         gint i;
68
69         for (i=0; i<tw->terms->len; ++i)
70         {
71                 TildaTerminal *tt = g_ptr_array_index (tw->terms, i);
72
73                 if (tt->number == terminal_number)
74                 {
75                         gint notebook_index = gtk_notebook_page_num (GTK_NOTEBOOK(tw->notebook), tt->hbox);
76
77                         /* Make sure the index was valid */
78                         if (notebook_index == -1)
79                         {
80                                 g_printerr ("DEBUG ERROR: Bad Notebook Tab\n");
81                                 return FALSE;
82                         }
83
84                         /* Actually remove the terminal */
85                         gtk_notebook_remove_page (GTK_NOTEBOOK (tw->notebook), notebook_index);
86
87                         /* We should hide the tabs if there is only one tab left */
88                         if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (tw->notebook)) == 1)
89                                 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (tw->notebook), FALSE);
90
91 #if 0
92                         // FIXME FIXME FIXME: need to actually do the stuff below
93                         /* With no pages left, it's time to leave the program */
94                         if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (tw->notebook)) < 1)
95                                 gtk_main_quit ();
96 #endif
97
98                         /* Remove the term from our lists, then free it */
99                         g_ptr_array_remove_fast (tw->terms, tt);
100                         g_object_unref (G_OBJECT(tt));
101
102                         /* Leave the loop, we're done */
103                         break;
104                 }
105         }
106
107         return TRUE;
108 }
109
110 /**
111  * This sets up the given TildaWindow for the capability of real
112  * transparency, if the X server is capable of it. */
113 static void
114 tilda_window_setup_real_transparency (TildaWindow *self)
115 {
116         GdkScreen *screen;
117         GdkColormap *colormap;
118
119         screen = gtk_widget_get_screen (GTK_WIDGET(self->window));
120         colormap = gdk_screen_get_rgba_colormap (screen);
121
122         /* If possible, set the RGBA colormap so VTE can use real alpha
123          * channels for transparency. */
124         if (colormap != NULL && gdk_screen_is_composited (screen))
125         {
126                 gtk_widget_set_colormap (GTK_WIDGET(self->window), colormap);
127                 self->have_real_transparency = TRUE;
128                 return;
129         }
130
131         self->have_real_transparency = FALSE;
132 }
133
134 static void
135 tilda_window_keybinding_cb (const gchar *keystr, gpointer data)
136 {
137         TildaWindow *self = TILDA_WINDOW(data);
138         g_print ("tilda_window_keybinding_cb() called! -- window %d\n", self->number);
139
140         // FIXME: this doesn't handle animation!
141
142         switch (self->state)
143         {
144                 case WINDOW_UP:
145                         /* Pull Down */
146                         tomboy_window_present_hardcore (GTK_WINDOW(self->window));
147                         self->state = WINDOW_DOWN;
148                         break;
149
150                 case WINDOW_DOWN:
151                         /* Pull Up */
152                         gtk_widget_hide (GTK_WIDGET(self->window));
153                         self->state = WINDOW_UP;
154                         break;
155
156                 default:
157                         g_printerr ("FIXME: the window is in a bad state!\n");
158
159                         /* Pretend we're down, for good measure.... */
160                         self->state = WINDOW_DOWN;
161                         break;
162         }
163 }
164
165 /**
166  * Attempt to bind the new_key to show this window.
167  *
168  * Return: TRUE if successful, FALSE otherwise.
169  */
170 static gboolean
171 tilda_window_try_to_bind_key (TildaWindow *self, const gchar *new_key)
172 {
173         gboolean ret = FALSE;
174
175         /* Make sure the new key is not null in any way */
176         if (new_key == NULL || strcmp("", new_key) == 0)
177                 return FALSE;
178
179         /* Unbind if we were set */
180         if (self->key)
181                 tomboy_keybinder_unbind (self->key, tilda_window_keybinding_cb, self);
182
183         ret = tomboy_keybinder_bind (new_key, tilda_window_keybinding_cb, self);
184
185         /* If it was successful, update the self->key variable and be done with it */
186         if (ret)
187         {
188                 g_free (self->key);
189                 self->key = g_strdup (new_key);
190                 return TRUE;
191         }
192
193         g_printerr ("Keybinding unsuccessful. Reverting to original key\n");
194
195         /* Not successful, so rebind the old key, and return FALSE */
196         if (self->key != NULL && strcmp("",self->key) != 0)
197         {
198                 ret = tomboy_keybinder_bind (self->key, tilda_window_keybinding_cb, self);
199
200                 /* Check that it went ok */
201                 if (!ret)
202                         g_printerr ("Unable to bind original key as well! Oh shit...\n");
203         }
204         else
205                 g_printerr ("No original key to revert to!\n");
206
207         return FALSE;
208 }
209
210 static void
211 tilda_window_dbus_register_object (TildaWindow *tw)
212 {
213         gchar *object_path;
214
215         // Register this object with DBus
216         object_path = g_strdup_printf ("/net/sourceforge/Tilda/Window%d", tw->number);
217         dbus_g_connection_register_g_object (dbus_connection, object_path, G_OBJECT(tw));
218         g_free (object_path);
219 }
220
221 /*******************************************************************************
222  * ALL GOBJECT STUFF BELOW PLEASE
223  ******************************************************************************/
224
225 static GObjectClass *parent_class = NULL;
226
227 enum tilda_window_properties {
228         TILDA_WINDOW_NUMBER = 1,
229
230         TILDA_WINDOW_KEY,
231
232         TILDA_WINDOW_MIN_HEIGHT,
233         TILDA_WINDOW_MIN_WIDTH,
234         TILDA_WINDOW_MAX_HEIGHT,
235         TILDA_WINDOW_MAX_WIDTH,
236         TILDA_WINDOW_X_POSITION,
237         TILDA_WINDOW_Y_POSITION,
238
239         TILDA_WINDOW_TAB_POSITION,
240         TILDA_WINDOW_ANIMATION_ORIENTATION,
241         TILDA_WINDOW_ANIMATION_DELAY,
242
243         TILDA_WINDOW_KEEP_ABOVE,
244         TILDA_WINDOW_SHOW_IN_TASKBAR,
245         TILDA_WINDOW_PINNED,
246         TILDA_WINDOW_HIDDEN_AT_START,
247         TILDA_WINDOW_CENTERED_HORIZONTALLY,
248         TILDA_WINDOW_CENTERED_VERTICALLY,
249
250         TILDA_WINDOW_HAVE_REAL_TRANSPARENCY,
251 };
252
253 static void
254 tilda_window_instance_init (GTypeInstance *instance,
255                                                         gpointer       g_class)
256 {
257         TildaWindow *self = (TildaWindow *) instance;
258         self->dispose_has_run = FALSE;
259
260         /* Initialize all properties */
261         self->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
262         self->notebook = gtk_notebook_new ();
263         self->terms = g_ptr_array_new ();
264
265         /* Somewhat of a "poison" value, incase we don't set this */
266         self->number = 0xdeadbeef;
267
268         self->state = WINDOW_UP;
269 }
270
271 static void
272 tilda_window_set_property (GObject      *object,
273                                                    guint         property_id,
274                                                    const GValue *value,
275                                                    GParamSpec   *pspec)
276 {
277         TildaWindow *self = (TildaWindow *) object;
278
279         switch (property_id) {
280
281                 case TILDA_WINDOW_NUMBER:
282                         self->number = g_value_get_int (value);
283                         g_print ("window number: %d\n", self->number);
284                         break;
285
286                 case TILDA_WINDOW_KEY:
287                         tilda_window_try_to_bind_key (self, g_value_get_string (value));
288                         g_print ("window key: %s\n", self->key);
289                         break;
290
291                 case TILDA_WINDOW_MIN_HEIGHT:
292                         self->min_height = g_value_get_int (value);
293                         g_print ("window min height: %d\n", self->min_height);
294                         break;
295
296                 case TILDA_WINDOW_MIN_WIDTH:
297                         self->min_width = g_value_get_int (value);
298                         g_print ("window min width: %d\n", self->min_width);
299                         break;
300
301                 case TILDA_WINDOW_MAX_HEIGHT:
302                         self->max_height = g_value_get_int (value);
303                         g_print ("window max height: %d\n", self->max_height);
304                         break;
305
306                 case TILDA_WINDOW_MAX_WIDTH:
307                         self->max_width = g_value_get_int (value);
308                         g_print ("window max width: %d\n", self->max_width);
309                         break;
310
311                 case TILDA_WINDOW_X_POSITION:
312                         self->x_position = g_value_get_int (value);
313                         g_print ("window x position: %d\n", self->x_position);
314                         break;
315
316                 case TILDA_WINDOW_Y_POSITION:
317                         self->y_position = g_value_get_int (value);
318                         g_print ("window y position: %d\n", self->y_position);
319                         break;
320
321                 case TILDA_WINDOW_TAB_POSITION:
322                         self->tab_position = g_value_get_int (value);
323                         g_print ("window tab position: %d\n", self->tab_position);
324                         break;
325
326                 case TILDA_WINDOW_ANIMATION_ORIENTATION:
327                         self->animation_orientation = g_value_get_int (value);
328                         g_print ("window animation orientation: %d\n", self->animation_orientation);
329                         break;
330
331                 case TILDA_WINDOW_ANIMATION_DELAY:
332                         self->animation_delay = g_value_get_int (value);
333                         g_print ("window animation delay: %d\n", self->animation_delay);
334                         break;
335
336                 case TILDA_WINDOW_KEEP_ABOVE:
337                         self->keep_above = g_value_get_boolean (value);
338                         g_print ("window keep above: %d\n", self->keep_above);
339                         break;
340
341                 case TILDA_WINDOW_SHOW_IN_TASKBAR:
342                         self->show_in_taskbar = g_value_get_boolean (value);
343                         g_print ("window show in taskbar: %d\n", self->show_in_taskbar);
344                         break;
345
346                 case TILDA_WINDOW_PINNED:
347                         self->pinned = g_value_get_boolean (value);
348                         g_print ("window pinned: %d\n", self->pinned);
349                         break;
350
351                 case TILDA_WINDOW_HIDDEN_AT_START:
352                         self->hidden_at_start = g_value_get_boolean (value);
353                         g_print ("window hidden at start: %d\n", self->hidden_at_start);
354                         break;
355
356                 case TILDA_WINDOW_CENTERED_HORIZONTALLY:
357                         self->centered_horizontally = g_value_get_boolean (value);
358                         g_print ("window centered horizontally: %d\n", self->centered_horizontally);
359                         break;
360
361                 case TILDA_WINDOW_CENTERED_VERTICALLY:
362                         self->centered_vertically = g_value_get_boolean (value);
363                         g_print ("window centered vertically: %d\n", self->centered_vertically);
364                         break;
365
366                 case TILDA_WINDOW_HAVE_REAL_TRANSPARENCY:
367                         self->have_real_transparency = g_value_get_boolean (value);
368                         g_print ("window have real transp: %d\n", self->have_real_transparency);
369                         break;
370
371                 default:
372                         /* We don't have this property */
373                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
374                         break;
375         }
376 }
377
378 static void
379 tilda_window_get_property (GObject    *object,
380                                                    guint       property_id,
381                                                    GValue     *value,
382                                                    GParamSpec *pspec)
383 {
384         TildaWindow *self = (TildaWindow *) object;
385
386         switch (property_id) {
387
388                 case TILDA_WINDOW_NUMBER:
389                         g_value_set_int (value, self->number);
390                         break;
391
392                 case TILDA_WINDOW_KEY:
393                         g_value_set_string (value, self->key);
394                         break;
395
396                 case TILDA_WINDOW_MIN_HEIGHT:
397                         g_value_set_int (value, self->min_height);
398                         break;
399
400                 case TILDA_WINDOW_MIN_WIDTH:
401                         g_value_set_int (value, self->min_width);
402                         break;
403
404                 case TILDA_WINDOW_MAX_HEIGHT:
405                         g_value_set_int (value, self->max_height);
406                         break;
407
408                 case TILDA_WINDOW_MAX_WIDTH:
409                         g_value_set_int (value, self->max_width);
410                         break;
411
412                 case TILDA_WINDOW_X_POSITION:
413                         g_value_set_int (value, self->x_position);
414                         break;
415
416                 case TILDA_WINDOW_Y_POSITION:
417                         g_value_set_int (value, self->y_position);
418                         break;
419
420                 case TILDA_WINDOW_TAB_POSITION:
421                         g_value_set_int (value, self->tab_position);
422                         break;
423
424                 case TILDA_WINDOW_ANIMATION_ORIENTATION:
425                         g_value_set_int (value, self->animation_orientation);
426                         break;
427
428                 case TILDA_WINDOW_ANIMATION_DELAY:
429                         g_value_set_int (value, self->animation_delay);
430                         break;
431
432                 case TILDA_WINDOW_KEEP_ABOVE:
433                         g_value_set_boolean (value, self->keep_above);
434                         break;
435
436                 case TILDA_WINDOW_SHOW_IN_TASKBAR:
437                         g_value_set_boolean (value, self->show_in_taskbar);
438                         break;
439
440                 case TILDA_WINDOW_PINNED:
441                         g_value_set_boolean (value, self->pinned);
442                         break;
443
444                 case TILDA_WINDOW_HIDDEN_AT_START:
445                         g_value_set_boolean (value, self->hidden_at_start);
446                         break;
447
448                 case TILDA_WINDOW_CENTERED_HORIZONTALLY:
449                         g_value_set_boolean (value, self->centered_horizontally);
450                         break;
451
452                 case TILDA_WINDOW_CENTERED_VERTICALLY:
453                         g_value_set_boolean (value, self->centered_vertically);
454                         break;
455
456                 case TILDA_WINDOW_HAVE_REAL_TRANSPARENCY:
457                         g_value_set_boolean (value, self->have_real_transparency);
458                         break;
459
460                 default:
461                         /* We don't have this property */
462                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
463                         break;
464         }
465 }
466
467 static GObject *
468 tilda_window_constructor (GType                  type,
469                                                   guint                  n_construct_properties,
470                                                   GObjectConstructParam *construct_properties)
471 {
472         GObject *obj;
473         TildaWindow *self;
474
475         /* Invoke parent constructor */
476         TildaWindowClass *klass;
477         klass = TILDA_WINDOW_CLASS (g_type_class_peek (TILDA_TYPE_WINDOW));
478         obj = parent_class->constructor (type,
479                                                                          n_construct_properties,
480                                                                          construct_properties);
481
482         /* Do other stuff here. The object is ready to go now, and all
483          * ctor properties have been set.
484          *
485          * TODO: This is the place to do DBus-init */
486         self = TILDA_WINDOW(obj);
487
488         /* Register this object with DBus */
489         tilda_window_dbus_register_object (self);
490
491         /* Try to set up real transparency */
492         tilda_window_setup_real_transparency (self);
493
494         gtk_container_add (GTK_CONTAINER(self->window), self->notebook);
495         gtk_widget_show (self->notebook);
496
497         tilda_window_add_term (self);
498         tilda_window_add_term (self);
499         gtk_widget_show_all (self->window);
500         self->state = WINDOW_DOWN;
501
502         return obj;
503 }
504
505 static void
506 my_unref (gpointer data, gpointer user_data)
507 {
508         g_object_unref (G_OBJECT(data));
509 }
510
511 static void
512 tilda_window_dispose (GObject *obj)
513 {
514         TildaWindow *self = (TildaWindow *) obj;
515
516         /* We don't want to run dispose twice, so just return immediately */
517         if (self->dispose_has_run)
518                 return;
519
520         /*
521          * In dispose, you are supposed to free all types referenced from this
522          * object which might themselves hold a reference to self. Generally,
523          * the most simple solution is to unref all members on which you own a
524          * reference.
525          *
526          * NOTE: See the following for how to deal with GtkObject-derived things:
527          * http://library.gnome.org/devel/gtk/unstable/GtkObject.html
528          */
529         g_ptr_array_foreach (self->terms, my_unref, NULL);
530         gtk_widget_destroy (self->window);
531
532         /* Chain up to the parent class */
533         G_OBJECT_CLASS (parent_class)->dispose (obj);
534 }
535
536 static void
537 tilda_window_finalize (GObject *obj)
538 {
539         TildaWindow *self = (TildaWindow *) obj;
540
541         /*
542          * Here, complete the object's destruction.
543          * You might not need to do much...
544          */
545         // TODO: g_free() any primitives here
546         g_ptr_array_free (self->terms, TRUE);
547
548
549         /* Chain up to the parent class */
550         G_OBJECT_CLASS (parent_class)->finalize (obj);
551 }
552
553 static void
554 tilda_window_class_init (gpointer g_class,
555                                                  gpointer g_class_data)
556 {
557         GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
558         TildaWindowClass *klass = TILDA_WINDOW_CLASS (g_class);
559         GParamSpec *pspec;
560
561         /* Hook our functions to this type */
562         gobject_class->set_property = tilda_window_set_property;
563         gobject_class->get_property = tilda_window_get_property;
564         gobject_class->dispose = tilda_window_dispose;
565         gobject_class->finalize = tilda_window_finalize;
566         gobject_class->constructor = tilda_window_constructor;
567
568         parent_class = g_type_class_peek_parent (klass);
569
570         /* Install all of the properties */
571         pspec = g_param_spec_int ("number",
572                                                           "Window number",
573                                                           "Set window's number",
574                                                           0,            // min value
575                                                           INT_MAX,      // max value
576                                                           0,            // def value
577                                                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
578
579         g_object_class_install_property (gobject_class,
580                                                                          TILDA_WINDOW_NUMBER,
581                                                                          pspec);
582
583         pspec = g_param_spec_string ("key",
584                                                                  "Window's drop-down keybinding",
585                                                                  NULL,
586                                                                  NULL,
587                                                                  G_PARAM_READWRITE);
588
589         g_object_class_install_property (gobject_class,
590                                                                          TILDA_WINDOW_KEY,
591                                                                          pspec);
592
593         pspec = g_param_spec_int ("min-height",
594                                                           "Window's minimum height",
595                                                           NULL,
596                                                           0,
597                                                           INT_MAX,
598                                                           0,
599                                                           G_PARAM_READWRITE);
600
601         g_object_class_install_property (gobject_class,
602                                                                          TILDA_WINDOW_MIN_HEIGHT,
603                                                                          pspec);
604
605         pspec = g_param_spec_int ("min-width",
606                                                           "Window's minimum width",
607                                                           NULL,
608                                                           0,
609                                                           INT_MAX,
610                                                           0,
611                                                           G_PARAM_READWRITE);
612
613         g_object_class_install_property (gobject_class,
614                                                                          TILDA_WINDOW_MIN_WIDTH,
615                                                                          pspec);
616
617         pspec = g_param_spec_int ("max-height",
618                                                           "Window's maximum height",
619                                                           NULL,
620                                                           0,
621                                                           INT_MAX,
622                                                           0,
623                                                           G_PARAM_READWRITE);
624
625         g_object_class_install_property (gobject_class,
626                                                                          TILDA_WINDOW_MAX_HEIGHT,
627                                                                          pspec);
628
629         pspec = g_param_spec_int ("max-width",
630                                                           "Window's maximum width",
631                                                           NULL,
632                                                           0,
633                                                           INT_MAX,
634                                                           0,
635                                                           G_PARAM_READWRITE);
636
637         g_object_class_install_property (gobject_class,
638                                                                          TILDA_WINDOW_MAX_WIDTH,
639                                                                          pspec);
640
641         pspec = g_param_spec_int ("x-position",
642                                                           "Window's x position",
643                                                           NULL,
644                                                           0,
645                                                           INT_MAX,
646                                                           0,
647                                                           G_PARAM_READWRITE);
648
649         g_object_class_install_property (gobject_class,
650                                                                          TILDA_WINDOW_X_POSITION,
651                                                                          pspec);
652
653         pspec = g_param_spec_int ("y-position",
654                                                           "Window's y position",
655                                                           NULL,
656                                                           0,
657                                                           INT_MAX,
658                                                           0,
659                                                           G_PARAM_READWRITE);
660
661         g_object_class_install_property (gobject_class,
662                                                                          TILDA_WINDOW_Y_POSITION,
663                                                                          pspec);
664
665         pspec = g_param_spec_int ("tab-position",
666                                                           "Window's tab position",
667                                                           NULL,
668                                                           0,
669                                                           INT_MAX,
670                                                           0,
671                                                           G_PARAM_READWRITE);
672
673         g_object_class_install_property (gobject_class,
674                                                                          TILDA_WINDOW_TAB_POSITION,
675                                                                          pspec);
676
677         pspec = g_param_spec_int ("animation-orientation",
678                                                           "Window's animation orientation",
679                                                           NULL,
680                                                           0,
681                                                           INT_MAX,
682                                                           0,
683                                                           G_PARAM_READWRITE);
684
685         g_object_class_install_property (gobject_class,
686                                                                          TILDA_WINDOW_ANIMATION_ORIENTATION,
687                                                                          pspec);
688
689         pspec = g_param_spec_int ("animation-delay",
690                                                           "Amount of time in milliseconds between animation intervals",
691                                                           NULL,
692                                                           0,
693                                                           INT_MAX,
694                                                           0,
695                                                           G_PARAM_READWRITE);
696
697         g_object_class_install_property (gobject_class,
698                                                                          TILDA_WINDOW_ANIMATION_DELAY,
699                                                                          pspec);
700
701         pspec = g_param_spec_boolean ("keep-above",
702                                                                   "Keep this window above all others",
703                                                                   NULL,
704                                                                   FALSE,
705                                                                   G_PARAM_READWRITE);
706
707         g_object_class_install_property (gobject_class,
708                                                                          TILDA_WINDOW_KEEP_ABOVE,
709                                                                          pspec);
710
711         pspec = g_param_spec_boolean ("show-in-taskbar",
712                                                                   "Show this window in the taskbar",
713                                                                   NULL,
714                                                                   FALSE,
715                                                                   G_PARAM_READWRITE);
716
717         g_object_class_install_property (gobject_class,
718                                                                          TILDA_WINDOW_SHOW_IN_TASKBAR,
719                                                                          pspec);
720
721         pspec = g_param_spec_boolean ("pinned",
722                                                                   "Display this window on all workspaces",
723                                                                   NULL,
724                                                                   FALSE,
725                                                                   G_PARAM_READWRITE);
726
727         g_object_class_install_property (gobject_class,
728                                                                          TILDA_WINDOW_PINNED,
729                                                                          pspec);
730
731         pspec = g_param_spec_boolean ("hidden-at-start",
732                                                                   "Hide the window when it is first created",
733                                                                   NULL,
734                                                                   FALSE,
735                                                                   G_PARAM_READWRITE);
736
737         g_object_class_install_property (gobject_class,
738                                                                          TILDA_WINDOW_HIDDEN_AT_START,
739                                                                          pspec);
740
741         pspec = g_param_spec_boolean ("centered-horizontally",
742                                                                   "Center the window horizontally",
743                                                                   NULL,
744                                                                   FALSE,
745                                                                   G_PARAM_READWRITE);
746
747         g_object_class_install_property (gobject_class,
748                                                                          TILDA_WINDOW_CENTERED_HORIZONTALLY,
749                                                                          pspec);
750
751         pspec = g_param_spec_boolean ("centered-vertically",
752                                                                   "Center the window vertically",
753                                                                   NULL,
754                                                                   FALSE,
755                                                                   G_PARAM_READWRITE);
756
757         g_object_class_install_property (gobject_class,
758                                                                          TILDA_WINDOW_CENTERED_VERTICALLY,
759                                                                          pspec);
760
761         pspec = g_param_spec_boolean ("have-real-transparency",
762                                                                   NULL, NULL, FALSE, G_PARAM_READABLE);
763
764         g_object_class_install_property (gobject_class,
765                                                                          TILDA_WINDOW_HAVE_REAL_TRANSPARENCY,
766                                                                          pspec);
767
768         /* TODO: more properties */
769
770         /* Hook the TildaWindow type into DBus */
771         dbus_g_object_type_install_info (tilda_window_get_type(), &dbus_glib_tilda_window_object_info);
772 }
773
774 GType
775 tilda_window_get_type (void)
776 {
777         static GType type = 0;
778
779         if (type == 0)
780         {
781                 static const GTypeInfo info = {
782                         sizeof (TildaWindowClass),
783                         NULL,   /* base_init */
784                         NULL,   /* base_finalize */
785                         tilda_window_class_init,        /* class_init */
786                         NULL,   /* class_finalize */
787                         NULL,   /* class_data */
788                         sizeof (TildaWindow),
789                         0,              /* n_preallocs */
790                         tilda_window_instance_init,     /* instance_init */
791                 };
792
793                 type = g_type_register_static (G_TYPE_OBJECT,
794                                                                            "TildaWindowType",
795                                                                            &info,
796                                                                            0);
797         }
798
799         return type;
800 }
801
802 #if 0
803
804 int main (int argc, char *argv[])
805 {
806         GObject *tw;
807         gint test_number = INT_MIN;
808
809         /* Initialize the GObject type system */
810         g_type_init ();
811         gtk_init (&argc, &argv);
812
813         tw = g_object_new (TILDA_TYPE_WINDOW, "number", 10, NULL);
814         g_object_get (G_OBJECT (tw), "number", &test_number, NULL);
815         g_assert (test_number == 10);
816
817         g_object_unref (G_OBJECT (tw));
818
819         tw = g_object_new (TILDA_TYPE_WINDOW, "number", 22, NULL);
820         g_object_get (G_OBJECT (tw), "number", &test_number, NULL);
821         g_assert (test_number == 22);
822
823         gtk_main ();
824
825         g_object_unref (G_OBJECT (tw));
826
827         return 0;
828 }
829
830 #endif
831
832 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */