LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-13-2007, 03:09 PM   #1
Frederick J. Harris
LQ Newbie
 
Registered: May 2007
Posts: 10

Rep: Reputation: 0
DestroyWindow Event In Xlib


I'm just trying to learn my way around Xlib, as I'm a Win32 programmer, and Xlib seems to be the closest counterpart to the Windows Api with Linux. I have various docs I've downloaded, and an old book vintage 1995 by Adrian Nye "Xlib Programming Manual". Anyway, in all the examples I've seen, it seems that everyone is doing absolutely everything remotely conceivable to skirt around the issue of trapping a DestroyWindow event so as to show how an application might call clean up code to release resources, etc. In Windows, if someone clicks the mouse on the little 'x' up in the upper right-hand corner of the window, Windows will send the window's Window Procedure a WM_CLOSE message. This gives an app time to call clean up procedures or bypass ending entirely.

After spending days trying to figure this out in Xlib I'm pretty much throwing up my hands in defeat! Below is the closest thing I have been able to come up with, but it does completely fail. The name of the program is CW2.c and at top is my command line for compiling it...

Code:
/*

   gcc CW2.c  -o CW2  -L/usr/X11R6/lib  -lX11

*/

#include <X11/Xlib.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
 Display* display;
 int blackColor,whiteColor;
 Window hRootWnd,hMainWnd;
 XEvent e;

 display=XOpenDisplay(0);
 if(!display)
    return 1;
 hRootWnd=DefaultRootWindow(display);
 printf("hRootWnd=%u\n",hRootWnd);
 blackColor=BlackPixel(display,DefaultScreen(display));
 whiteColor=WhitePixel(display,DefaultScreen(display));
 hMainWnd=
 XCreateSimpleWindow
 (
     display,
     DefaultRootWindow(display),
     200,200,400,350,0,
     blackColor,
     whiteColor
 );
 printf("hMainWnd=%u\n",hMainWnd);
 XSelectInput(display,hRootWnd,SubstructureNotifyMask);
 XMapWindow(display,hMainWnd);
 while(1)
 {
  XNextEvent(display,&e);
  switch(e.type)
  {
   case Expose:
     printf("Received Expose Event!\n");
     break;
   case MapNotify:
     printf("Received MapNotify Event!\n");
     break;
   case UnmapNotify:
     printf("Received UnmapNotify Event!\n");
     break;
   case ConfigureNotify:
     printf("Received ConfigureNotify Event!\n");
     break;
   case DestroyNotify:
     if(e.xdestroywindow.window==hRootWnd)
     {
        printf
        (
         "Received DestroyNotify Event From hRootWnd! -- hRootWnd=%u\n",
         e.xdestroywindow.window
        );
        XCloseDisplay(display);
        exit(1);
     }
     if(e.xdestroywindow.window==hMainWnd)
     {
        printf
        (
         "Received DestroyNotify Event For Main Window! -- hMainWnd=%u\n",
         e.xdestroywindow.window
        );
        XCloseDisplay(display);
        exit(1);
     }
     else
     {
        printf
        (
         "Received DestroyNotify Event But Not For Any Known Window! -- e.xdestroywindow.window=%u\n",
         e.xdestroywindow.window
        );
        XCloseDisplay(display);
        exit(1);
     }
     break;
   default:
     break;
  }
 }

 return 0;
}
In terms of explanation, note that I defined two variables to hold what I'd refer to in Windows as window handles, i.e., the variables returned by a CreateWindow() call, here XCreateSimpleWindow(). I've come to understand that the main desktop window is called the 'Root Window', and that the DefaultRootWindow(display) function returns a window handle (id in Linux speak) for that window. I've further come to understand that the DestroyWindow event can only be caught by the parent of the main app through a

XSelectInput(display,hRootWnd,SubstructureNotifyMask);

call with SubstructureNotifyMask for the mask parameter. I've fooled around with all types of masks with both the root window and the main window, but under no circumstanes can I figure out a fool proof way of determining when the 'x' button on the main app window has been clicked. Below is the Terminal output from the above program showing compilation through a run of the program...

Code:
fredharris@CODEWARRIOR:~/CloseWindow$ gcc CW2.c  -o CW2  -L/usr/X11R6/lib  -lX11
fredharris@CODEWARRIOR:~/CloseWindow$ ./CW2
hRootWnd=69
hMainWnd=41943041
Received ConfigureNotify Event!
Received ConfigureNotify Event!
Received ConfigureNotify Event!
Received MapNotify Event!
Received UnmapNotify Event!
Received UnmapNotify Event!
Received ConfigureNotify Event!
Received ConfigureNotify Event!
Received MapNotify Event!
Received UnmapNotify Event!
Received UnmapNotify Event!
Received DestroyNotify Event But Not For Any Known Window! -- e.xdestroywindow.window=10552202
fredharris@CODEWARRIOR:~/CloseWindow$
Interestingly, the code above was able to catch a DestroyNotify event, but not for any window known to this application! Note that I printf'd the root window id ( 69 ), and the main windows's id (41,943,041), but the e.xdestroywindow.window's id pertaining to the DestroyWindow event was 10,552,202! Now which window is that? Would anyone be able to set me on the path to figuring out how to catch an app termination event caused by a click on the little 'x' in the title bar of the window???

Fred
 
Old 05-13-2007, 03:42 PM   #2
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
X Window leaves you the choice of a graphic environment, and especially a window manager.
The foreign window id is likely to belong to your window manager which uses it to reparent your main window.
 
Old 05-13-2007, 06:08 PM   #3
Frederick J. Harris
LQ Newbie
 
Registered: May 2007
Posts: 10

Original Poster
Rep: Reputation: 0
Unhappy reparenting?

Then the answer to my question as to how to trap a DestroyWindow message from my app's window somehow involves the concept of re-parenting? As you can tell I'm just feeling my way here gingerly through unfamiliar territory. The whole concept of a 'window manager' is new to me. I'm not sure if in Windows there is any corresponding concept. I believe not. So I have something to learn there. Still studying...
 
Old 05-13-2007, 08:44 PM   #4
Frederick J. Harris
LQ Newbie
 
Registered: May 2007
Posts: 10

Original Poster
Rep: Reputation: 0
jlliagre,

You didn't give me much, but perhaps enough! On page 514 of the aformentioned book in chapter 16 'Window Management' I found some discussion of the topic of 'Substructure redirection' and 'Reparenting'. The paragraph starts as follows...

'A window manager can decorate windows on the screen with titlebars and place little boxes on the titlebar with which the window can be moved or resized. This is only one possibility, modeled on the user interface of the Macintosh.'

'To do this the window manager creates a child of the root somewhat larger than the top-level window of the application. Then it calls XReparentWindow(), specifying the top-level window of the application as win, and the new parent as parent.'

I'm assuming what I now need to determine is a way to get that new 'enclosig' windows's id so as to test it in a case DestroyWindow. Any thoughts...
 
Old 05-13-2007, 11:41 PM   #5
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi -

Here's an explanation of how Windows managers interact with Xlib; one that might help clarify the jlliagre's comments about "reparenting", etc:

http://en.wikipedia.org/wiki/X_window_manager

The central problem is that Xlib very deliberately separates "mechanism" (the raw, Xlib-level "plumbing") from "policy". It's better design, it afford greater flexibility ... but it's confusing for folks who come from a Microsoft world where everything's all jumbled together (the API is the Window manager is the OS...)

You can find several possible solutions here:
comp.windows.x, search for "Close Window" and "DestroyNotify":
http://groups.google.com/group/comp.windows.x

'Hope that helps .. PSM
 
Old 05-14-2007, 05:59 AM   #6
Frederick J. Harris
LQ Newbie
 
Registered: May 2007
Posts: 10

Original Poster
Rep: Reputation: 0
Thanks PSAULSM4. I'll be away for next two days but will thereafter get back at this!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Xlib: connection to ":0.0" refused by server Xlib: No protocol specified eyalkz Linux - Newbie 12 11-27-2018 01:30 PM
Timer Event wallwaters Linux - Software 1 05-26-2005 09:46 PM
Event logging RajaRC Linux - Networking 2 10-28-2004 12:59 AM
Xlib: connection to ":0.0" refused by server Xlib: No protocol specified eyalkz Programming 1 03-02-2004 08:22 AM
Event Sounds.. jhorvath Slackware 2 10-01-2002 04:13 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:16 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration