1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * Test of focus.
4  *
5  * This program tests whether focus reverts to another window when
6  * the focused window resizes out from under the cursor.
7  * Some window managers have this bug, while others don't.
8  * It only matters when you're using pointer focus, not click-to-type.
9  *
10  * It also tests whether gtk_window_present() can take the focus
11  * for window managers that have this bug. See the call to
12  * gtk_window_present() in line 62.
13  *
14  * To test:
15  *   1. Make sure you have pointer focus set.
16  *   2. Compile, then run focustest.
17  *   3. Spacebar will toggle between portrait and landscape shaped windows.
18  *      Toggle a few times to see.
19  *   4. Put your mouse in a place where it's in the window, but once
20  *      the window resizes the mouse will be outside the window and
21  *      in another window underneath.
22  *   5. Hit spacebar to toggle, and see if the window loses focus.
23  *
24  *   If it does lose focus, then uncomment the call to gtk_window_present()
25  *   (line 62) and try again. See if it's any better.
26  *
27  * Copyright 2007 by Akkana Peck.
28  * You are free to use or modify this code under the Gnu Public License.
29  *
30  * Sample compile line:
31  * cc -g -Wall -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -o focustest focustest.c -lgtk-x11-2.0 -lgdk-x11-2.0 -lX11
32  */
33 
34 #include <stdlib.h>       /* for getenv() */
35 #include <stdio.h>
36 #include <string.h>
37 #include <ctype.h>
38 
39 #include <gtk/gtk.h>
40 #include <gdk/gdk.h>
41 #include <gdk/gdkkeysyms.h>
42 
43 #include <gdk/gdkx.h>    /* for gdk_x11_display_grab */
44 
45 GtkWidget *gWin = 0;
46 static GtkWidget *sDrawingArea = 0;
47 static gint gMonitorWidth, gMonitorHeight;
48 
HandleKeys(GtkWidget * widget,GdkEventKey * event)49 gint HandleKeys(GtkWidget* widget, GdkEventKey* event)
50 {
51     gint width, height;
52     switch (event->keyval)
53     {
54       case GDK_space:  /* swap dimensions */
55           gdk_drawable_get_size(sDrawingArea->window, &width, &height);
56           gtk_window_resize(GTK_WINDOW(gWin), height, width);
57 
58           /* The next line tries to set focus explicitly.
59            * Comment it out if you're just trying to find out
60            * whether your windowmanager has the bug.
61            */
62           //gtk_window_present(GTK_WINDOW(gWin));
63           return TRUE;
64       case GDK_q:
65         exit(0);
66     }
67     return FALSE;
68 }
69 
main(int argc,char ** argv)70 int main(int argc, char** argv)
71 {
72     gtk_init(&argc, &argv);
73 
74     gMonitorWidth = gdk_screen_width();
75     gMonitorHeight = gdk_screen_height();
76 
77     /* Make it possible to resize smaller as well as larger: */
78     gWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
79 
80     gtk_widget_set_size_request(GTK_WIDGET(gWin), 1, 1);
81 
82     /* Window manager delete */
83     gtk_signal_connect(GTK_OBJECT(gWin), "delete_event",
84                        (GtkSignalFunc)exit, 0);
85 
86     /* This event occurs when we call gtk_widget_destroy() on the window,
87      * or if we return FALSE in the "delete_event" callback.
88     gtk_signal_connect(GTK_OBJECT(gWin), "destroy",
89                        (GtkSignalFunc)HandleDestroy, 0);
90      */
91 
92     /* KeyPress events on the drawing area don't come through --
93      * they have to be on the window.
94      */
95     gtk_signal_connect(GTK_OBJECT(gWin), "key_press_event",
96                        (GtkSignalFunc)HandleKeys, 0);
97 
98     sDrawingArea = gtk_drawing_area_new();
99     gtk_container_add(GTK_CONTAINER(gWin), sDrawingArea);
100     gtk_widget_show(sDrawingArea);
101 
102     gtk_drawing_area_size(GTK_DRAWING_AREA(sDrawingArea), 800, 600);
103     gtk_window_resize(GTK_WINDOW(gWin), 800, 600);
104 
105     gtk_widget_show(gWin);
106 
107     gtk_main();
108     return 0;
109 }
110 
111