metacity-window-demo.c

Go to the documentation of this file.
00001 /* Metacity window types/properties demo app */
00002 
00003 /* 
00004  * Copyright (C) 2002 Havoc Pennington
00005  * 
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License as
00008  * published by the Free Software Foundation; either version 2 of the
00009  * License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful, but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00019  * 02111-1307, USA.
00020  */
00021 
00022 #include <gtk/gtk.h>
00023 #include <gdk/gdkx.h>
00024 #include <X11/Xatom.h>
00025 #include <unistd.h>
00026 
00027 static GtkWidget* do_appwindow (void);
00028 
00029 static gboolean aspect_on;
00030 
00031 static void
00032 set_gdk_window_struts (GdkWindow *window,
00033                        int        left,
00034                        int        right,
00035                        int        top,
00036                        int        bottom)
00037 {
00038   long vals[12];
00039   
00040   vals[0] = left;
00041   vals[1] = right;
00042   vals[2] = top;
00043   vals[3] = bottom;
00044   vals[4] = 000;
00045   vals[5] = 400;
00046   vals[6] = 200;
00047   vals[7] = 600;
00048   vals[8] = 76;
00049   vals[9] = 676;
00050   vals[10] = 200;
00051   vals[11] = 800;
00052 
00053   XChangeProperty (GDK_WINDOW_XDISPLAY (window),
00054                    GDK_WINDOW_XWINDOW (window),
00055                    XInternAtom (GDK_WINDOW_XDISPLAY (window),
00056                                 "_NET_WM_STRUT_PARTIAL", False),
00057                    XA_CARDINAL, 32, PropModeReplace,
00058                    (guchar *)vals, 12);
00059 }
00060 
00061 static void
00062 on_realize_set_struts (GtkWindow *window,
00063                        gpointer   data)
00064 {
00065   int left;
00066   int right;
00067   int top;
00068   int bottom;
00069 
00070   g_return_if_fail (GTK_WIDGET_REALIZED (window));
00071 
00072   left = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-left"));
00073   right = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-right"));
00074   top = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-top"));
00075   bottom = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-bottom"));
00076   
00077   set_gdk_window_struts (GTK_WIDGET (window)->window,
00078                          left, right, top, bottom);
00079 }
00080 
00081 static void
00082 set_gtk_window_struts (GtkWidget  *window,
00083                        int         left,
00084                        int         right,
00085                        int         top,
00086                        int         bottom)
00087 {
00088   g_object_set_data (G_OBJECT (window), "meta-strut-left",
00089                      GINT_TO_POINTER (left));
00090   g_object_set_data (G_OBJECT (window), "meta-strut-right",
00091                      GINT_TO_POINTER (right));
00092   g_object_set_data (G_OBJECT (window), "meta-strut-top",
00093                      GINT_TO_POINTER (top));
00094   g_object_set_data (G_OBJECT (window), "meta-strut-bottom",
00095                      GINT_TO_POINTER (bottom));
00096   
00097   g_signal_handlers_disconnect_by_func (G_OBJECT (window),
00098                                         on_realize_set_struts,
00099                                         NULL);
00100                                 
00101   g_signal_connect_after (G_OBJECT (window),
00102                           "realize",
00103                           G_CALLBACK (on_realize_set_struts),
00104                           NULL);
00105 
00106   if (GTK_WIDGET_REALIZED (window))
00107     set_gdk_window_struts (GTK_WIDGET (window)->window,
00108                            left, right, top, bottom);
00109 }
00110 
00111 static void
00112 set_gdk_window_type (GdkWindow  *window,
00113                      const char *type)
00114 {
00115   Atom atoms[2] = { None, None };
00116   
00117   atoms[0] = XInternAtom (GDK_WINDOW_XDISPLAY (window),
00118                           type, False);
00119   
00120   XChangeProperty (GDK_WINDOW_XDISPLAY (window),
00121                    GDK_WINDOW_XWINDOW (window),
00122                    XInternAtom (GDK_WINDOW_XDISPLAY (window), "_NET_WM_WINDOW_TYPE", False),
00123                    XA_ATOM, 32, PropModeReplace,
00124                    (guchar *)atoms, 
00125                    1);
00126 }
00127 
00128 static void
00129 on_realize_set_type (GtkWindow *window,
00130                      gpointer   data)
00131 {
00132   const char *type;
00133 
00134   g_return_if_fail (GTK_WIDGET_REALIZED (window));
00135 
00136   type = g_object_get_data (G_OBJECT (window), "meta-window-type");
00137 
00138   g_return_if_fail (type != NULL);
00139   
00140   set_gdk_window_type (GTK_WIDGET (window)->window,
00141                        type);
00142 }
00143 
00144 static void
00145 set_gtk_window_type (GtkWindow  *window,
00146                      const char *type)
00147 {
00148   g_object_set_data (G_OBJECT (window), "meta-window-type", (char*) type);
00149 
00150   g_signal_handlers_disconnect_by_func (G_OBJECT (window),
00151                                         on_realize_set_type,
00152                                         NULL);
00153                                 
00154   g_signal_connect_after (G_OBJECT (window),
00155                           "realize",
00156                           G_CALLBACK (on_realize_set_type),
00157                           NULL);
00158 
00159   if (GTK_WIDGET_REALIZED (window))
00160     set_gdk_window_type (GTK_WIDGET (window)->window,
00161                          type);
00162 }
00163 
00164 static void
00165 set_gdk_window_border_only (GdkWindow *window)
00166 {
00167   gdk_window_set_decorations (window, GDK_DECOR_BORDER);
00168 }
00169 
00170 static void
00171 on_realize_set_border_only (GtkWindow *window,
00172                             gpointer   data)
00173 {
00174   g_return_if_fail (GTK_WIDGET_REALIZED (window));
00175   
00176   set_gdk_window_border_only (GTK_WIDGET (window)->window);
00177 }
00178 
00179 static void
00180 set_gtk_window_border_only (GtkWindow  *window)
00181 {
00182   g_signal_handlers_disconnect_by_func (G_OBJECT (window),
00183                                         on_realize_set_border_only,
00184                                         NULL);
00185                                 
00186   g_signal_connect_after (G_OBJECT (window),
00187                           "realize",
00188                           G_CALLBACK (on_realize_set_border_only),
00189                           NULL);
00190 
00191   if (GTK_WIDGET_REALIZED (window))
00192     set_gdk_window_border_only (GTK_WIDGET (window)->window);
00193 }
00194 
00195 int
00196 main (int argc, char **argv)
00197 {
00198   GList *list;
00199   GdkPixbuf *pixbuf;
00200   GError *err;
00201   
00202   gtk_init (&argc, &argv);
00203 
00204   err = NULL;
00205   pixbuf = gdk_pixbuf_new_from_file (METACITY_ICON_DIR"/metacity-window-demo.png",
00206                                      &err);
00207   if (pixbuf)
00208     {
00209       list = g_list_prepend (NULL, pixbuf);
00210       
00211       gtk_window_set_default_icon_list (list);
00212       g_list_free (list);
00213       g_object_unref (G_OBJECT (pixbuf));
00214     }
00215   else
00216     {
00217       g_printerr ("Could not load icon: %s\n", err->message);
00218       g_error_free (err);
00219     }
00220   
00221   do_appwindow ();
00222 
00223   gtk_main ();
00224   
00225   return 0;
00226 }
00227 
00228 static void
00229 response_cb (GtkDialog *dialog,
00230              int        response_id,
00231              void      *data);
00232 
00233 static void
00234 make_dialog (GtkWidget *parent,
00235              int        depth)
00236 {
00237   GtkWidget *dialog;
00238   char *str;
00239   
00240   dialog = gtk_message_dialog_new (parent ? GTK_WINDOW (parent) : NULL,
00241                                    GTK_DIALOG_DESTROY_WITH_PARENT,
00242                                    GTK_MESSAGE_INFO,
00243                                    GTK_BUTTONS_CLOSE,
00244                                    parent ? "Here is a dialog %d" :
00245                                    "Here is a dialog %d with no transient parent",
00246                                    depth);
00247 
00248   str = g_strdup_printf ("%d dialog", depth);
00249   gtk_window_set_title (GTK_WINDOW (dialog), str);
00250   g_free (str);
00251   
00252   gtk_dialog_add_button (GTK_DIALOG (dialog),
00253                          "Open child dialog",
00254                          GTK_RESPONSE_ACCEPT);
00255   
00256   /* Close dialog on user response */
00257   g_signal_connect (G_OBJECT (dialog),
00258                     "response",
00259                     G_CALLBACK (response_cb),
00260                     NULL);
00261 
00262   g_object_set_data (G_OBJECT (dialog), "depth",
00263                      GINT_TO_POINTER (depth));
00264   
00265   gtk_widget_show (dialog);
00266 }
00267 
00268 static void
00269 response_cb (GtkDialog *dialog,
00270              int        response_id,
00271              void      *data)
00272 {
00273   switch (response_id)
00274     {
00275     case GTK_RESPONSE_ACCEPT:
00276       make_dialog (GTK_WIDGET (dialog),
00277                    GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog),
00278                                                        "depth")) + 1);
00279       break;
00280 
00281     default:
00282       gtk_widget_destroy (GTK_WIDGET (dialog));
00283       break;
00284     }
00285 }
00286 
00287 static void
00288 dialog_cb (gpointer             callback_data,
00289            guint                callback_action,
00290            GtkWidget           *widget)
00291 {
00292   make_dialog (GTK_WIDGET (callback_data), 1);
00293 }
00294 
00295 static void
00296 modal_dialog_cb (gpointer             callback_data,
00297                  guint                callback_action,
00298                  GtkWidget           *widget)
00299 {
00300   GtkWidget *dialog;
00301   
00302   dialog = gtk_message_dialog_new (GTK_WINDOW (callback_data),
00303                                    GTK_DIALOG_DESTROY_WITH_PARENT,
00304                                    GTK_MESSAGE_INFO,
00305                                    GTK_BUTTONS_CLOSE,
00306                                    "Here is a MODAL dialog");
00307 
00308   set_gtk_window_type (GTK_WINDOW (dialog), "_NET_WM_WINDOW_TYPE_MODAL_DIALOG");
00309   
00310   gtk_dialog_run (GTK_DIALOG (dialog));
00311 
00312   gtk_widget_destroy (dialog);
00313 }
00314 
00315 static void
00316 no_parent_dialog_cb (gpointer             callback_data,
00317                      guint                callback_action,
00318                      GtkWidget           *widget)
00319 {
00320   make_dialog (NULL, 1);
00321 }
00322 
00323 static void
00324 utility_cb (gpointer             callback_data,
00325             guint                callback_action,
00326             GtkWidget           *widget)
00327 {
00328   GtkWidget *window;
00329   GtkWidget *vbox;
00330   GtkWidget *button;
00331   
00332   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00333   set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_UTILITY");
00334   gtk_window_set_title (GTK_WINDOW (window), "Utility");
00335   
00336   gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data));
00337   
00338   vbox = gtk_vbox_new (FALSE, 0);
00339 
00340   gtk_container_add (GTK_CONTAINER (window), vbox);
00341 
00342   button = gtk_button_new_with_mnemonic ("_A button");
00343   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
00344 
00345   button = gtk_button_new_with_mnemonic ("_B button");
00346   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
00347 
00348   button = gtk_button_new_with_mnemonic ("_C button");
00349   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
00350 
00351   button = gtk_button_new_with_mnemonic ("_D button");
00352   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
00353   
00354   gtk_widget_show_all (window);
00355 }
00356 
00357 static void
00358 toolbar_cb (gpointer             callback_data,
00359             guint                callback_action,
00360             GtkWidget           *widget)
00361 {
00362   GtkWidget *window;
00363   GtkWidget *vbox;
00364   GtkWidget *label;
00365   
00366   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00367   set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_TOOLBAR");
00368   gtk_window_set_title (GTK_WINDOW (window), "Toolbar");
00369   
00370   gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data));
00371   
00372   vbox = gtk_vbox_new (FALSE, 0);
00373 
00374   gtk_container_add (GTK_CONTAINER (window), vbox);
00375 
00376   label = gtk_label_new ("FIXME this needs a resize grip, etc.");
00377   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
00378   
00379   gtk_widget_show_all (window);
00380 }
00381 
00382 static void
00383 menu_cb (gpointer             callback_data,
00384          guint                callback_action,
00385          GtkWidget           *widget)
00386 {
00387   GtkWidget *window;
00388   GtkWidget *vbox;
00389   GtkWidget *label;
00390   
00391   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00392   set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_MENU");
00393   gtk_window_set_title (GTK_WINDOW (window), "Menu");
00394   
00395   gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data));
00396   
00397   vbox = gtk_vbox_new (FALSE, 0);
00398 
00399   gtk_container_add (GTK_CONTAINER (window), vbox);
00400 
00401   label = gtk_label_new ("FIXME this isn't a menu.");
00402   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
00403   
00404   gtk_widget_show_all (window);
00405 }
00406 
00407 static void
00408 override_redirect_cb (gpointer             callback_data,
00409                       guint                callback_action,
00410                       GtkWidget           *widget)
00411 {
00412   GtkWidget *window;
00413   GtkWidget *vbox;
00414   GtkWidget *label;
00415   
00416   window = gtk_window_new (GTK_WINDOW_POPUP);
00417   gtk_window_set_title (GTK_WINDOW (window), "Override Redirect");
00418   
00419   vbox = gtk_vbox_new (FALSE, 0);
00420 
00421   gtk_container_add (GTK_CONTAINER (window), vbox);
00422 
00423   label = gtk_label_new ("This is an override\nredirect window\nand should not be managed");
00424   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
00425   
00426   gtk_widget_show_all (window);
00427 }
00428 
00429 static void
00430 border_only_cb (gpointer             callback_data,
00431                 guint                callback_action,
00432                 GtkWidget           *widget)
00433 {
00434   GtkWidget *window;
00435   GtkWidget *vbox;
00436   GtkWidget *label;
00437   
00438   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00439   set_gtk_window_border_only (GTK_WINDOW (window));
00440   gtk_window_set_title (GTK_WINDOW (window), "Border only");
00441   
00442   gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data));
00443   
00444   vbox = gtk_vbox_new (FALSE, 0);
00445 
00446   gtk_container_add (GTK_CONTAINER (window), vbox);
00447 
00448   label = gtk_label_new ("This window is supposed to have a border but no titlebar.");
00449   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
00450   
00451   gtk_widget_show_all (window);
00452 }
00453 
00454 #if 0
00455 static void
00456 changing_icon_cb (gpointer             callback_data,
00457                   guint                callback_action,
00458                   GtkWidget           *widget)
00459 {
00460   GtkWidget *window;
00461   GtkWidget *vbox;
00462   GtkWidget *label;
00463   
00464   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00465   gtk_window_set_title (GTK_WINDOW (window), "Changing Icon");
00466   
00467   vbox = gtk_vbox_new (FALSE, 0);
00468 
00469   gtk_container_add (GTK_CONTAINER (window), vbox);
00470 
00471   label = gtk_label_new ("This window has an icon that changes over time");
00472   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
00473   
00474   gtk_widget_show_all (window);
00475 }
00476 #endif
00477 
00478 static gboolean
00479 focus_in_event_cb (GtkWidget *window,
00480                    GdkEvent  *event,
00481                    gpointer   data)
00482 {
00483   GtkWidget *widget;
00484 
00485   widget = GTK_WIDGET (data);
00486 
00487   gtk_label_set_text (GTK_LABEL (widget), "Has focus");
00488 
00489   return TRUE;
00490 }
00491 
00492 
00493 static gboolean
00494 focus_out_event_cb (GtkWidget *window,
00495                     GdkEvent  *event,
00496                     gpointer   data)
00497 {
00498   GtkWidget *widget;
00499 
00500   widget = GTK_WIDGET (data);
00501 
00502   gtk_label_set_text (GTK_LABEL (widget), "Not focused");
00503   
00504   return TRUE;
00505 }
00506 
00507 static GtkWidget*
00508 focus_label (GtkWidget *window)
00509 {
00510   GtkWidget *label;
00511   
00512   label = gtk_label_new ("Not focused");
00513 
00514   g_signal_connect (G_OBJECT (window), "focus_in_event",
00515                     G_CALLBACK (focus_in_event_cb), label);
00516 
00517   g_signal_connect (G_OBJECT (window), "focus_out_event",
00518                     G_CALLBACK (focus_out_event_cb), label);
00519   
00520   return label;
00521 }
00522 
00523 static void
00524 splashscreen_cb (gpointer             callback_data,
00525                  guint                callback_action,
00526                  GtkWidget           *widget)
00527 {
00528   GtkWidget *window;
00529   GtkWidget *image;
00530   GtkWidget *vbox;
00531   
00532   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00533   set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_SPLASHSCREEN");
00534   gtk_window_set_title (GTK_WINDOW (window), "Splashscreen");
00535   
00536   vbox = gtk_vbox_new (FALSE, 0);
00537   
00538   image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
00539   gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
00540 
00541   gtk_box_pack_start (GTK_BOX (vbox), focus_label (window), FALSE, FALSE, 0);  
00542   
00543   gtk_container_add (GTK_CONTAINER (window), vbox);
00544   
00545   gtk_widget_show_all (window);
00546 }
00547 
00548 enum
00549 {
00550   DOCK_TOP = 1,
00551   DOCK_BOTTOM = 2,
00552   DOCK_LEFT = 3,
00553   DOCK_RIGHT = 4,
00554   DOCK_ALL = 5
00555 };
00556 
00557 static void
00558 make_dock (int type)
00559 {
00560   GtkWidget *window;
00561   GtkWidget *image;
00562   GtkWidget *box;
00563   GtkWidget *button;
00564 
00565   g_return_if_fail (type != DOCK_ALL);
00566 
00567   box = NULL;
00568   switch (type)
00569     {
00570     case DOCK_LEFT:
00571     case DOCK_RIGHT:      
00572       box = gtk_vbox_new (FALSE, 0);
00573       break;
00574     case DOCK_TOP:
00575     case DOCK_BOTTOM:
00576       box = gtk_hbox_new (FALSE, 0);
00577       break;
00578     case DOCK_ALL:
00579       break;
00580     }
00581 
00582   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00583   set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_DOCK");
00584   
00585   image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
00586   gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);  
00587   
00588   gtk_box_pack_start (GTK_BOX (box), focus_label (window), FALSE, FALSE, 0);  
00589 
00590   button = gtk_button_new_with_label ("Close");
00591   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
00592 
00593   g_signal_connect_swapped (G_OBJECT (button), "clicked",
00594                             G_CALLBACK (gtk_widget_destroy), window);
00595   
00596   gtk_container_add (GTK_CONTAINER (window), box);
00597 
00598 #define DOCK_SIZE 48
00599   switch (type)
00600     {
00601     case DOCK_LEFT:
00602       gtk_widget_set_size_request (window, DOCK_SIZE, 400);
00603       gtk_window_move (GTK_WINDOW (window), 0, 000);
00604       set_gtk_window_struts (window, DOCK_SIZE, 0, 0, 0);
00605       gtk_window_set_title (GTK_WINDOW (window), "LeftDock");
00606       break;
00607     case DOCK_RIGHT:      
00608       gtk_widget_set_size_request (window, DOCK_SIZE, 400);
00609       gtk_window_move (GTK_WINDOW (window), gdk_screen_width () - DOCK_SIZE, 200);
00610       set_gtk_window_struts (window, 0, DOCK_SIZE, 0, 0);
00611       gtk_window_set_title (GTK_WINDOW (window), "RightDock");
00612       break;
00613     case DOCK_TOP:
00614       gtk_widget_set_size_request (window, 600, DOCK_SIZE);
00615       gtk_window_move (GTK_WINDOW (window), 76, 0);
00616       set_gtk_window_struts (window, 0, 0, DOCK_SIZE, 0);
00617       gtk_window_set_title (GTK_WINDOW (window), "TopDock");
00618       break;
00619     case DOCK_BOTTOM:
00620       gtk_widget_set_size_request (window, 600, DOCK_SIZE);
00621       gtk_window_move (GTK_WINDOW (window), 200, gdk_screen_height () - DOCK_SIZE);
00622       set_gtk_window_struts (window, 0, 0, 0, DOCK_SIZE);
00623       gtk_window_set_title (GTK_WINDOW (window), "BottomDock");
00624       break;
00625     case DOCK_ALL:
00626       break;
00627     }
00628   
00629   gtk_widget_show_all (window);
00630 }
00631 
00632 static void
00633 dock_cb (gpointer             callback_data,
00634          guint                callback_action,
00635          GtkWidget           *widget)
00636 {
00637   if (callback_action == DOCK_ALL)
00638     {
00639       make_dock (DOCK_TOP);
00640       make_dock (DOCK_BOTTOM);
00641       make_dock (DOCK_LEFT);
00642       make_dock (DOCK_RIGHT);
00643     }
00644   else
00645     {
00646       make_dock (callback_action);
00647     }
00648 }
00649 
00650 static void
00651 desktop_cb (gpointer             callback_data,
00652             guint                callback_action,
00653             GtkWidget           *widget)
00654 {
00655   GtkWidget *window;
00656   GtkWidget *label;
00657   GdkColor desktop_color;
00658   
00659   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00660   set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_DESKTOP");
00661   gtk_window_set_title (GTK_WINDOW (window), "Desktop");
00662   gtk_widget_set_size_request (window,
00663                                gdk_screen_width (), gdk_screen_height ());
00664   gtk_window_move (GTK_WINDOW (window), 0, 0);
00665   
00666   desktop_color.red = 0x5144;
00667   desktop_color.green = 0x75D6;
00668   desktop_color.blue = 0xA699;
00669 
00670   gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &desktop_color);
00671   
00672   label = focus_label (window);
00673   
00674   gtk_container_add (GTK_CONTAINER (window), label);
00675   
00676   gtk_widget_show_all (window);
00677 }
00678 
00679 static GtkItemFactoryEntry menu_items[] =
00680 {
00681   { "/_Windows",              NULL,         NULL,                     0, "<Branch>" },
00682   { "/Windows/tearoff",       NULL,         NULL,                     0, "<Tearoff>" },
00683   { "/Windows/_Dialog",       "<control>d",  dialog_cb,               0, NULL },
00684   { "/Windows/_Modal dialog", NULL,          modal_dialog_cb,         0, NULL },
00685   { "/Windows/_Parentless dialog", NULL,     no_parent_dialog_cb,     0, NULL },
00686   { "/Windows/_Utility",      "<control>u",  utility_cb,              0, NULL },
00687   { "/Windows/_Splashscreen", "<control>s",  splashscreen_cb,         0, NULL },
00688   { "/Windows/_Top dock",     NULL,          dock_cb,                 DOCK_TOP, NULL },
00689   { "/Windows/_Bottom dock",  NULL,          dock_cb,                 DOCK_BOTTOM, NULL },
00690   { "/Windows/_Left dock",    NULL,          dock_cb,                 DOCK_LEFT, NULL },
00691   { "/Windows/_Right dock",   NULL,          dock_cb,                 DOCK_RIGHT, NULL },
00692   { "/Windows/_All docks",    NULL,          dock_cb,                 DOCK_ALL, NULL },
00693   { "/Windows/Des_ktop",      NULL,          desktop_cb,              0, NULL },
00694   { "/Windows/Me_nu",         NULL,          menu_cb,                 0, NULL },
00695   { "/Windows/Tool_bar",      NULL,          toolbar_cb,              0, NULL },
00696   { "/Windows/Override Redirect",      NULL,          override_redirect_cb,              0, NULL },
00697   { "/Windows/Border Only",      NULL,          border_only_cb,              0, NULL }
00698 };
00699 
00700 static void
00701 sleep_cb (GtkWidget *button,
00702           gpointer   data)
00703 {
00704   sleep (1000);
00705 }
00706 
00707 static void
00708 toggle_aspect_ratio (GtkWidget *button,
00709                      gpointer   data)
00710 {
00711   GtkWidget *window;
00712   GdkGeometry geom;
00713 
00714   if (aspect_on)
00715     {
00716       geom.min_aspect = 0;
00717       geom.max_aspect = 65535;
00718     }
00719   else
00720     {
00721       geom.min_aspect = 1.777778;
00722       geom.max_aspect = 1.777778;
00723     }
00724 
00725   aspect_on = !aspect_on;
00726 
00727   window = gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW);
00728   if (window)
00729     gtk_window_set_geometry_hints (GTK_WINDOW (window),
00730                                    GTK_WIDGET (data),
00731                                    &geom,
00732                                    GDK_HINT_ASPECT);
00733                                    
00734 }
00735 
00736 static void
00737 toggle_decorated_cb (GtkWidget *button,
00738                      gpointer   data)
00739 {
00740   GtkWidget *window;
00741   window = gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW);
00742   if (window)
00743     gtk_window_set_decorated (GTK_WINDOW (window),
00744                               !gtk_window_get_decorated (GTK_WINDOW (window)));
00745 }
00746 
00747 static void
00748 clicked_toolbar_cb (GtkWidget *button,
00749                     gpointer   data)
00750 {
00751   GtkWidget *dialog;
00752   
00753   dialog = gtk_message_dialog_new (GTK_WINDOW (data),
00754                                    GTK_DIALOG_DESTROY_WITH_PARENT,
00755                                    GTK_MESSAGE_INFO,
00756                                    GTK_BUTTONS_CLOSE,
00757                                    "Clicking the toolbar buttons doesn't do anything");
00758 
00759   /* Close dialog on user response */
00760   g_signal_connect (G_OBJECT (dialog),
00761                     "response",
00762                     G_CALLBACK (gtk_widget_destroy),
00763                     NULL);
00764   
00765   gtk_widget_show (dialog);
00766 }
00767 
00768 static void
00769 update_statusbar (GtkTextBuffer *buffer,
00770                   GtkStatusbar  *statusbar)
00771 {
00772   gchar *msg;
00773   gint row, col;
00774   gint count;
00775   GtkTextIter iter;
00776   
00777   gtk_statusbar_pop (statusbar, 0); /* clear any previous message, underflow is allowed */
00778 
00779   count = gtk_text_buffer_get_char_count (buffer);
00780 
00781   gtk_text_buffer_get_iter_at_mark (buffer,
00782                                     &iter,
00783                                     gtk_text_buffer_get_insert (buffer));
00784 
00785   row = gtk_text_iter_get_line (&iter);
00786   col = gtk_text_iter_get_line_offset (&iter);
00787 
00788   msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",
00789                          row, col, count);
00790 
00791   gtk_statusbar_push (statusbar, 0, msg);
00792 
00793   g_free (msg);
00794 }
00795 
00796 static void
00797 mark_set_callback (GtkTextBuffer     *buffer,
00798                    const GtkTextIter *new_location,
00799                    GtkTextMark       *mark,
00800                    gpointer           data)
00801 {
00802   update_statusbar (buffer, GTK_STATUSBAR (data));
00803 }
00804 
00805 static int window_count = 0;
00806 
00807 static void
00808 destroy_cb (GtkWidget *w, gpointer data)
00809 {
00810   --window_count;
00811   if (window_count == 0)
00812     gtk_main_quit ();
00813 }
00814 
00815 static GtkWidget *
00816 do_appwindow (void)
00817 {
00818   GtkWidget *window;
00819   GtkWidget *table;
00820   GtkWidget *toolbar;
00821   GtkWidget *handlebox;
00822   GtkWidget *statusbar;
00823   GtkWidget *contents;
00824   GtkWidget *sw;
00825   GtkTextBuffer *buffer;
00826   GtkAccelGroup *accel_group;      
00827   GtkItemFactory *item_factory;
00828       
00829   /* Create the toplevel window
00830    */
00831 
00832   ++window_count;
00833 
00834   aspect_on = FALSE;
00835 
00836   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00837   gtk_window_set_title (GTK_WINDOW (window), "Application Window");
00838   
00839   g_signal_connect (G_OBJECT (window), "destroy",
00840                     G_CALLBACK (destroy_cb), NULL);
00841       
00842   table = gtk_table_new (1, 4, FALSE);
00843       
00844   gtk_container_add (GTK_CONTAINER (window), table);
00845       
00846   /* Create the menubar
00847    */
00848       
00849   accel_group = gtk_accel_group_new ();
00850   gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
00851   g_object_unref (accel_group);
00852       
00853   item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
00854 
00855   /* Set up item factory to go away with the window */
00856   g_object_ref (item_factory);
00857   gtk_object_sink (GTK_OBJECT (item_factory));
00858   g_object_set_data_full (G_OBJECT (window),
00859                           "<main>",
00860                           item_factory,
00861                           (GDestroyNotify) g_object_unref);
00862 
00863   /* create menu items */
00864   gtk_item_factory_create_items (item_factory, G_N_ELEMENTS (menu_items),
00865                                  menu_items, window);
00866 
00867   gtk_table_attach (GTK_TABLE (table),
00868                     gtk_item_factory_get_widget (item_factory, "<main>"),
00869                     /* X direction */          /* Y direction */
00870                     0, 1,                      0, 1,
00871                     GTK_EXPAND | GTK_FILL,     0,
00872                     0,                         0);
00873 
00874   /* Create document
00875    */
00876 
00877   sw = gtk_scrolled_window_new (NULL, NULL);
00878 
00879   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
00880                                   GTK_POLICY_AUTOMATIC,
00881                                   GTK_POLICY_AUTOMATIC);
00882 
00883   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
00884                                        GTK_SHADOW_IN);
00885       
00886   gtk_table_attach (GTK_TABLE (table),
00887                     sw,
00888                     /* X direction */       /* Y direction */
00889                     0, 1,                   2, 3,
00890                     GTK_EXPAND | GTK_FILL,  GTK_EXPAND | GTK_FILL,
00891                     0,                      0);
00892 
00893   gtk_window_set_default_size (GTK_WINDOW (window),
00894                                200, 200);
00895       
00896   contents = gtk_text_view_new ();
00897   gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (contents),
00898                                PANGO_WRAP_WORD);
00899       
00900   gtk_container_add (GTK_CONTAINER (sw),
00901                      contents);
00902 
00903   /* Create the toolbar
00904    */
00905   toolbar = gtk_toolbar_new ();
00906 
00907   gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
00908                             GTK_STOCK_NEW,
00909                             "Open another one of these windows",
00910                             NULL,
00911                             G_CALLBACK (do_appwindow),
00912                             window, /* user data for callback */
00913                             -1);  /* -1 means "append" */
00914   
00915   gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
00916                             GTK_STOCK_OPEN,
00917                             "This is a demo button that locks up the demo",
00918                             NULL,
00919                             G_CALLBACK (sleep_cb),
00920                             window, /* user data for callback */
00921                             -1);  /* -1 means "append" */
00922 
00923   gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
00924                             GTK_STOCK_OPEN,
00925                             "This is a demo button that toggles window decorations",
00926                             NULL,
00927                             G_CALLBACK (toggle_decorated_cb),
00928                             window, /* user data for callback */
00929                             -1);  /* -1 means "append" */
00930   
00931   gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
00932                             GTK_STOCK_OPEN,
00933                             "This is a demo button that locks the aspect ratio using a hint",
00934                             NULL,
00935                             G_CALLBACK (toggle_aspect_ratio),
00936                             contents, /* user data for callback */
00937                             -1);  /* -1 means "append" */
00938   
00939   gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
00940                             GTK_STOCK_QUIT,
00941                             "This is a demo button with a 'quit' icon",
00942                             NULL,
00943                             G_CALLBACK (clicked_toolbar_cb),
00944                             window, /* user data for callback */
00945                             -1);  /* -1 means "append" */
00946 
00947   handlebox = gtk_handle_box_new ();
00948 
00949   gtk_container_add (GTK_CONTAINER (handlebox), toolbar);
00950       
00951   gtk_table_attach (GTK_TABLE (table),
00952                     handlebox,
00953                     /* X direction */       /* Y direction */
00954                     0, 1,                   1, 2,
00955                     GTK_EXPAND | GTK_FILL,  0,
00956                     0,                      0);
00957 
00958   /* Create statusbar */
00959 
00960   statusbar = gtk_statusbar_new ();
00961   gtk_table_attach (GTK_TABLE (table),
00962                     statusbar,
00963                     /* X direction */       /* Y direction */
00964                     0, 1,                   3, 4,
00965                     GTK_EXPAND | GTK_FILL,  0,
00966                     0,                      0);
00967 
00968   /* Show text widget info in the statusbar */
00969   buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents));
00970 
00971   gtk_text_buffer_set_text (buffer,
00972                             "This demo demonstrates various kinds of windows that "
00973                             "window managers and window manager themes should handle. "
00974                             "Be sure to tear off the menu and toolbar, those are also "
00975                             "a special kind of window.",
00976                             -1);
00977       
00978   g_signal_connect_object (buffer,
00979                            "changed",
00980                            G_CALLBACK (update_statusbar),
00981                            statusbar,
00982                            0);
00983 
00984   g_signal_connect_object (buffer,
00985                            "mark_set", /* cursor moved */
00986                            G_CALLBACK (mark_set_callback),
00987                            statusbar,
00988                            0);
00989       
00990   update_statusbar (buffer, GTK_STATUSBAR (statusbar));
00991 
00992   gtk_widget_show_all (window);
00993 
00994   return window;
00995 }
00996 
00997 

Generated on Sat Aug 23 22:04:18 2008 for metacity by  doxygen 1.5.5