This commit is contained in:
rhp 2001-06-04 06:17:52 +00:00
parent 1cd2915ba3
commit ad6efc61b5
4 changed files with 153 additions and 19 deletions

View File

@ -68,7 +68,15 @@ meta_display_open (const char *name)
GSList *screens; GSList *screens;
GSList *tmp; GSList *tmp;
int i; int i;
char *atom_names[] = { "_NET_WM_NAME", "WM_PROTOCOLS", "WM_TAKE_FOCUS", "WM_DELETE_WINDOW" }; /* Remember to edit code that assigns each atom to display struct
* when adding an atom name here.
*/
char *atom_names[] = {
"_NET_WM_NAME",
"WM_PROTOCOLS",
"WM_TAKE_FOCUS",
"WM_DELETE_WINDOW"
};
Atom atoms[G_N_ELEMENTS(atom_names)]; Atom atoms[G_N_ELEMENTS(atom_names)];
meta_verbose ("Opening display '%s'\n", XDisplayName (name)); meta_verbose ("Opening display '%s'\n", XDisplayName (name));
@ -136,6 +144,9 @@ meta_display_open (const char *name)
XInternAtoms (display->xdisplay, atom_names, G_N_ELEMENTS (atom_names), XInternAtoms (display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
False, atoms); False, atoms);
display->atom_net_wm_name = atoms[0]; display->atom_net_wm_name = atoms[0];
display->atom_wm_protocols = atoms[1];
display->atom_wm_take_focus = atoms[2];
display->atom_wm_delete_window = atoms[3];
/* Now manage all existing windows */ /* Now manage all existing windows */
tmp = display->screens; tmp = display->screens;
@ -184,6 +195,8 @@ meta_display_close (MetaDisplay *display)
winlist = g_slist_sort (winlist, ptrcmp); winlist = g_slist_sort (winlist, ptrcmp);
/* Unmanage all windows */
meta_display_grab (display);
tmp = winlist; tmp = winlist;
while (tmp != NULL) while (tmp != NULL)
{ {
@ -194,6 +207,7 @@ meta_display_close (MetaDisplay *display)
tmp = tmp->next; tmp = tmp->next;
} }
g_slist_free (winlist); g_slist_free (winlist);
meta_display_ungrab (display);
/* Must be after all calls to meta_window_free() since they /* Must be after all calls to meta_window_free() since they
* unregister windows * unregister windows
@ -397,10 +411,16 @@ event_queue_callback (MetaEventQueue *queue,
meta_window_free (window); /* Unmanage destroyed window */ meta_window_free (window); /* Unmanage destroyed window */
break; break;
case UnmapNotify: case UnmapNotify:
if (window) if (window && window->mapped)
meta_window_free (window); /* Unmanage withdrawn window */ {
meta_verbose ("Window %s withdrawn\n",
window->desc);
meta_window_free (window); /* Unmanage withdrawn window */
}
break; break;
case MapNotify: case MapNotify:
if (window)
window->mapped = TRUE;
break; break;
case MapRequest: case MapRequest:
if (window == NULL) if (window == NULL)
@ -414,6 +434,8 @@ event_queue_callback (MetaEventQueue *queue,
/* Unmanage it, override_redirect was toggled on? /* Unmanage it, override_redirect was toggled on?
* Can this happen? * Can this happen?
*/ */
meta_verbose ("Window %s toggled on override redirect\n",
window->desc);
meta_window_free (window); meta_window_free (window);
} }
break; break;

View File

@ -29,7 +29,7 @@ meta_frame_init_info (MetaFrame *frame,
MetaFrameInfo *info) MetaFrameInfo *info)
{ {
info->flags = info->flags =
META_FRAME_ALLOWS_DELETE | META_FRAME_ALLOWS_MENU | META_FRAME_ALLOWS_MENU | META_FRAME_ALLOWS_DELETE |
META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE | META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE |
META_FRAME_ALLOWS_RESIZE; META_FRAME_ALLOWS_RESIZE;
@ -198,9 +198,6 @@ meta_window_ensure_frame (MetaWindow *window)
if (window->frame) if (window->frame)
return; return;
/* Need to fix Pango, it grabs the server */
g_return_if_fail (window->display->server_grab_count == 0);
frame = g_new (MetaFrame, 1); frame = g_new (MetaFrame, 1);
@ -262,6 +259,9 @@ meta_window_ensure_frame (MetaWindow *window)
meta_display_grab (window->display); meta_display_grab (window->display);
meta_error_trap_push (window->display); meta_error_trap_push (window->display);
window->mapped = FALSE; /* the reparent will unmap the window,
* we don't want to take that as a withdraw
*/
XReparentWindow (window->display->xdisplay, XReparentWindow (window->display->xdisplay,
window->xwindow, window->xwindow,
frame->xwindow, frame->xwindow,
@ -274,8 +274,9 @@ meta_window_ensure_frame (MetaWindow *window)
window->rect.y = frame->child_y; window->rect.y = frame->child_y;
/* stick frame to the window */ /* stick frame to the window */
window->frame = frame; window->frame = frame;
/* Put our state back where it should be */
if (window->iconic) if (window->iconic)
meta_window_hide (window); meta_window_hide (window);
else else
@ -306,6 +307,10 @@ meta_window_destroy_frame (MetaWindow *window)
* thus the error trap. * thus the error trap.
*/ */
meta_error_trap_push (window->display); meta_error_trap_push (window->display);
window->mapped = FALSE; /* Keep track of unmapping it, so we
* can identify a withdraw initiated
* by the client.
*/
XReparentWindow (window->display->xdisplay, XReparentWindow (window->display->xdisplay,
window->xwindow, window->xwindow,
window->screen->xroot, window->screen->xroot,
@ -323,6 +328,12 @@ meta_window_destroy_frame (MetaWindow *window)
XDestroyWindow (window->display->xdisplay, frame->xwindow); XDestroyWindow (window->display->xdisplay, frame->xwindow);
g_free (frame); g_free (frame);
/* Put our state back where it should be */
if (window->iconic)
meta_window_hide (window);
else
meta_window_show (window);
} }
void void

View File

@ -121,12 +121,16 @@ meta_window_new (MetaDisplay *display, Window xwindow)
window->xvisual = attrs.visual; window->xvisual = attrs.visual;
window->title = NULL; window->title = NULL;
window->iconic = FALSE;
window->desc = g_strdup_printf ("0x%lx", window->xwindow); window->desc = g_strdup_printf ("0x%lx", window->xwindow);
window->frame = NULL; window->frame = NULL;
window->has_focus = FALSE; window->has_focus = FALSE;
window->initially_iconic = FALSE;
window->minimized = FALSE;
window->iconic = FALSE;
window->mapped = FALSE;
meta_display_register_x_window (display, &window->xwindow, window); meta_display_register_x_window (display, &window->xwindow, window);
@ -134,10 +138,24 @@ meta_window_new (MetaDisplay *display, Window xwindow)
update_title (window); update_title (window);
update_protocols (window); update_protocols (window);
update_wm_hints (window); update_wm_hints (window);
if (window->initially_iconic)
{
/* WM_HINTS said iconic */
window->iconic = TRUE;
}
meta_window_resize (window, window->size_hints.width, window->size_hints.height); meta_window_resize (window, window->size_hints.width, window->size_hints.height);
meta_window_ensure_frame (window); meta_window_ensure_frame (window);
/* Put our state where it should be (ensure_frame also did this
* for decorated windows, but should be harmless to do twice)
*/
if (window->iconic)
meta_window_hide (window);
else
meta_window_show (window);
return window; return window;
} }
@ -150,6 +168,15 @@ meta_window_free (MetaWindow *window)
meta_display_unregister_x_window (window->display, window->xwindow); meta_display_unregister_x_window (window->display, window->xwindow);
meta_window_destroy_frame (window); meta_window_destroy_frame (window);
/* Put back anything we messed up */
meta_error_trap_push (window->display);
if (window->border_width != 0)
XSetWindowBorderWidth (window->display->xdisplay,
window->xwindow,
window->border_width);
meta_error_trap_pop (window->display);
g_free (window->title); g_free (window->title);
g_free (window->desc); g_free (window->desc);
@ -163,7 +190,15 @@ meta_window_show (MetaWindow *window)
XMapWindow (window->display->xdisplay, window->frame->xwindow); XMapWindow (window->display->xdisplay, window->frame->xwindow);
XMapWindow (window->display->xdisplay, window->xwindow); XMapWindow (window->display->xdisplay, window->xwindow);
/* These flags aren't always in sync, iconic
* is set only here in show/hide, mapped
* can be set in a couple other places where
* we map/unmap
*/
window->mapped = TRUE;
window->iconic = FALSE; window->iconic = FALSE;
/* FIXME update WM_STATE */
} }
void void
@ -173,7 +208,30 @@ meta_window_hide (MetaWindow *window)
XUnmapWindow (window->display->xdisplay, window->frame->xwindow); XUnmapWindow (window->display->xdisplay, window->frame->xwindow);
XUnmapWindow (window->display->xdisplay, window->xwindow); XUnmapWindow (window->display->xdisplay, window->xwindow);
window->mapped = FALSE;
window->iconic = TRUE; window->iconic = TRUE;
/* FIXME update WM_STATE */
}
void
meta_window_minimize (MetaWindow *window)
{
if (!window->minimized)
{
window->minimized = TRUE;
meta_window_hide (window);
}
}
void
meta_window_unminimize (MetaWindow *window)
{
if (window->minimized)
{
window->minimized = FALSE;
meta_window_show (window);
}
} }
void void
@ -206,9 +264,20 @@ meta_window_delete (MetaWindow *window,
Time timestamp) Time timestamp)
{ {
meta_error_trap_push (window->display); meta_error_trap_push (window->display);
meta_window_send_icccm_message (window, if (window->delete_window)
window->display->atom_wm_delete_window, {
timestamp); meta_verbose ("Deleting %s with delete_window request\n",
window->desc);
meta_window_send_icccm_message (window,
window->display->atom_wm_delete_window,
timestamp);
}
else
{
meta_verbose ("Deleting %s with explicit kill\n",
window->desc);
XKillClient (window->display->xdisplay, window->xwindow);
}
meta_error_trap_pop (window->display); meta_error_trap_pop (window->display);
} }
@ -319,6 +388,13 @@ process_property_notify (MetaWindow *window,
{ {
update_protocols (window); update_protocols (window);
if (window->frame)
meta_frame_queue_recalc (window->frame);
}
else if (event->atom == XA_WM_HINTS)
{
update_wm_hints (window);
if (window->frame) if (window->frame)
meta_frame_queue_recalc (window->frame); meta_frame_queue_recalc (window->frame);
} }
@ -698,7 +774,7 @@ update_protocols (MetaWindow *window)
if (XGetWMProtocols (window->display->xdisplay, if (XGetWMProtocols (window->display->xdisplay,
window->xwindow, window->xwindow,
&protocols, &protocols,
&n_protocols) == Success) &n_protocols))
{ {
i = 0; i = 0;
while (i < n_protocols) while (i < n_protocols)
@ -727,6 +803,7 @@ update_wm_hints (MetaWindow *window)
/* Fill in defaults */ /* Fill in defaults */
window->input = FALSE; window->input = FALSE;
window->initially_iconic = FALSE;
meta_error_trap_push (window->display); meta_error_trap_push (window->display);
@ -735,9 +812,14 @@ update_wm_hints (MetaWindow *window)
if (hints) if (hints)
{ {
window->input = (hints->flags & InputHint) != 0; window->input = (hints->flags & InputHint) != 0;
window->initially_iconic = (hints->initial_state == IconicState);
/* FIXME there are a few others there. */ /* FIXME there are a few others there. */
meta_verbose ("Read WM_HINTS input: %d iconic: %d\n",
window->input, window->initially_iconic);
XFree (hints); XFree (hints);
} }

View File

@ -37,8 +37,25 @@ struct _MetaWindow
Visual *xvisual; Visual *xvisual;
char *desc; /* used in debug spew */ char *desc; /* used in debug spew */
char *title; char *title;
/* Mapped is what we think the mapped state should be;
* so if we get UnmapNotify and mapped == TRUE then
* it's a withdraw, if mapped == FALSE the UnmapNotify
* is caused by us.
*/
guint mapped : 1;
/* Minimize is the state controlled by the minimize button */
guint minimized : 1;
/* Iconic is the state in WM_STATE; happens for workspaces/shading
* in addition to minimize
*/
guint iconic : 1; guint iconic : 1;
/* initially_iconic is the WM_HINTS setting when we first manage
* the window.
*/
guint initially_iconic : 1;
/* These are the two flags from WM_PROTOCOLS */
guint take_focus : 1; guint take_focus : 1;
guint delete_window : 1; guint delete_window : 1;
/* Globally active / No input */ /* Globally active / No input */
@ -58,11 +75,13 @@ struct _MetaWindow
XSizeHints size_hints; XSizeHints size_hints;
}; };
MetaWindow* meta_window_new (MetaDisplay *display, MetaWindow* meta_window_new (MetaDisplay *display,
Window xwindow); Window xwindow);
void meta_window_free (MetaWindow *window); void meta_window_free (MetaWindow *window);
void meta_window_show (MetaWindow *window); void meta_window_show (MetaWindow *window);
void meta_window_hide (MetaWindow *window); void meta_window_hide (MetaWindow *window);
void meta_window_minimize (MetaWindow *window);
void meta_window_unminimize (MetaWindow *window);
void meta_window_resize (MetaWindow *window, void meta_window_resize (MetaWindow *window,
int w, int w,
int h); int h);