By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,963 Members | 1,260 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,963 IT Pros & Developers. It's quick & easy.

Why is this Xlib program not detecting focus change events in C?

Laserblade
P: 2
I'm having a hard time detecting XMaskEvents in C using Xlib. I want my program to be alerted whenever a window gets the focus and when it loses its focus.

Here is my code:
Expand|Select|Wrap|Line Numbers
  1. #include <gtk/gtk.h>
  2. #include <gtk/gtkx.h>
  3. #include <X11/Xlib.h>
  4. #include <stdlib.h>
  5.  
  6. static void activate (GtkApplication* app, gpointer user_data) 
  7. {
  8.     GtkWidget *window;
  9.     GtkWidget *glblLabel = gtk_label_new("Hello!");
  10.     GdkWindow *gdkwin; 
  11.     GdkDisplay *gdkdisplay;
  12.     Display *dpy;
  13.     Window xwindow;
  14.     int screen_num = 0;
  15.     int intvar = 0;
  16.     int *revert_to = &intvar;
  17.     unsigned int size = snprintf(NULL, 0, "%lu", ULONG_MAX);
  18.     char *text = malloc(size);
  19.     XEvent xevent;
  20.  
  21.     if (text == NULL) {
  22.         printf("Not enough memory to malloc for char *text\n");
  23.         exit(EXIT_FAILURE);
  24.     } 
  25.  
  26.     // Set up the application, window, and widgets
  27.     window = gtk_application_window_new (app);
  28.     gtk_window_set_title (GTK_WINDOW (window), "Window");
  29.     gtk_window_set_default_size (GTK_WINDOW (window), 200, 200); 
  30.     gtk_container_add(GTK_CONTAINER(window), glblLabel);
  31.     gtk_widget_show_all (window);
  32.  
  33.     // Get GtkWidget *window's GdkWindow
  34.     gdkwin = gtk_widget_get_window(window);
  35.  
  36.     // Then use it to get its GdkDisplay
  37.     gdkdisplay = gdk_window_get_display(gdkwin);
  38.  
  39.     // Use that to get its X11 display
  40.     dpy = GDK_DISPLAY_XDISPLAY(gdkdisplay);
  41.  
  42.     // Get GtkWidget *window's X window ID
  43.     xwindow = GDK_WINDOW_XID(gdkwin);
  44.  
  45.     // Get the active window ID to display it in the label
  46.     XGetInputFocus(dpy, &xwindow, revert_to); 
  47.  
  48.     // Check to see if a string was actually copied to "text"
  49.     if (sprintf(text, "%lu", xwindow) <= 0) {
  50.         printf("sprintf wrote 0 bytes to text\n");
  51.         exit(EXIT_FAILURE);
  52.     }; 
  53.  
  54.     gtk_label_set_text(GTK_LABEL(glblLabel), text);
  55.  
  56.     screen_num = DefaultScreen(dpy);
  57.     XSelectInput(dpy, RootWindow(dpy, screen_num), FocusChangeMask);
  58.  
  59.     while (1) {
  60.         XNextEvent(dpy, &xevent);
  61.  
  62.         switch (xevent.type) {
  63.         case FocusChangeMask:
  64.             XMaskEvent(dpy, FocusChangeMask, &xevent);
  65.             if ((xevent.type == FocusIn) || (xevent.type == FocusOut)) printf("Keyboard focus has changed\n");
  66.             break;
  67.         }
  68.     }
  69.  
  70. }
  71.  
  72.  
  73. int main (int  argc, char **argv) 
  74. {
  75.     GtkApplication    *app;
  76.     int         status;
  77.  
  78.     app = gtk_application_new ("org.website.inputfocus3", G_APPLICATION_FLAGS_NONE);
  79.     g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  80.     status = g_application_run (G_APPLICATION (app), argc, argv);
  81.     g_object_unref (app);
  82.  
  83.     return status;
  84. }
Unfortunately, I get no output when I click on other apps and windows. This was a continuation of an earlier program I wrote. The only difference between this one and the previous program, is the addition of lines 56-68, which would make
Expand|Select|Wrap|Line Numbers
  1. gtk_label_set_text(GTK_LABEL(glblLabel), text);
the last statement in that function. That program appears to work, displaying a number in the label. However, when I run this program, the entire app's window goes black when it runs, and clicking on the X in the upper corner to close it doesn't work. I have to hit Ctrl+C to kill it.

If anybody can show me what I'm doing wrong, I would greatly appreciate it. Thank you
Dec 10 '17 #1

✓ answered by Laserblade

I found that this can be done by using libwnck.

Share this Question
Share on Google+
1 Reply


Laserblade
P: 2
I found that this can be done by using libwnck.
Dec 22 '17 #2

Post your reply

Sign in to post your reply or Sign up for a free account.