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 *tmp;
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)];
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),
False, atoms);
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 */
tmp = display->screens;
@ -184,6 +195,8 @@ meta_display_close (MetaDisplay *display)
winlist = g_slist_sort (winlist, ptrcmp);
/* Unmanage all windows */
meta_display_grab (display);
tmp = winlist;
while (tmp != NULL)
{
@ -194,6 +207,7 @@ meta_display_close (MetaDisplay *display)
tmp = tmp->next;
}
g_slist_free (winlist);
meta_display_ungrab (display);
/* Must be after all calls to meta_window_free() since they
* unregister windows
@ -397,10 +411,16 @@ event_queue_callback (MetaEventQueue *queue,
meta_window_free (window); /* Unmanage destroyed window */
break;
case UnmapNotify:
if (window)
if (window && window->mapped)
{
meta_verbose ("Window %s withdrawn\n",
window->desc);
meta_window_free (window); /* Unmanage withdrawn window */
}
break;
case MapNotify:
if (window)
window->mapped = TRUE;
break;
case MapRequest:
if (window == NULL)
@ -414,6 +434,8 @@ event_queue_callback (MetaEventQueue *queue,
/* Unmanage it, override_redirect was toggled on?
* Can this happen?
*/
meta_verbose ("Window %s toggled on override redirect\n",
window->desc);
meta_window_free (window);
}
break;

View File

@ -29,7 +29,7 @@ meta_frame_init_info (MetaFrame *frame,
MetaFrameInfo *info)
{
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_RESIZE;
@ -199,9 +199,6 @@ meta_window_ensure_frame (MetaWindow *window)
if (window->frame)
return;
/* Need to fix Pango, it grabs the server */
g_return_if_fail (window->display->server_grab_count == 0);
frame = g_new (MetaFrame, 1);
/* Fill in values that calc_geometry will use */
@ -262,6 +259,9 @@ meta_window_ensure_frame (MetaWindow *window)
meta_display_grab (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,
window->xwindow,
frame->xwindow,
@ -276,6 +276,7 @@ meta_window_ensure_frame (MetaWindow *window)
/* stick frame to the window */
window->frame = frame;
/* Put our state back where it should be */
if (window->iconic)
meta_window_hide (window);
else
@ -306,6 +307,10 @@ meta_window_destroy_frame (MetaWindow *window)
* thus the error trap.
*/
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,
window->xwindow,
window->screen->xroot,
@ -323,6 +328,12 @@ meta_window_destroy_frame (MetaWindow *window)
XDestroyWindow (window->display->xdisplay, frame->xwindow);
g_free (frame);
/* Put our state back where it should be */
if (window->iconic)
meta_window_hide (window);
else
meta_window_show (window);
}
void

View File

@ -121,13 +121,17 @@ meta_window_new (MetaDisplay *display, Window xwindow)
window->xvisual = attrs.visual;
window->title = NULL;
window->iconic = FALSE;
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
window->frame = NULL;
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);
update_size_hints (window);
@ -135,10 +139,24 @@ meta_window_new (MetaDisplay *display, Window xwindow)
update_protocols (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_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;
}
@ -151,6 +169,15 @@ meta_window_free (MetaWindow *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->desc);
g_free (window);
@ -163,7 +190,15 @@ meta_window_show (MetaWindow *window)
XMapWindow (window->display->xdisplay, window->frame->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;
/* FIXME update WM_STATE */
}
void
@ -173,7 +208,30 @@ meta_window_hide (MetaWindow *window)
XUnmapWindow (window->display->xdisplay, window->frame->xwindow);
XUnmapWindow (window->display->xdisplay, window->xwindow);
window->mapped = FALSE;
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
@ -206,9 +264,20 @@ meta_window_delete (MetaWindow *window,
Time timestamp)
{
meta_error_trap_push (window->display);
if (window->delete_window)
{
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);
}
@ -319,6 +388,13 @@ process_property_notify (MetaWindow *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)
meta_frame_queue_recalc (window->frame);
}
@ -698,7 +774,7 @@ update_protocols (MetaWindow *window)
if (XGetWMProtocols (window->display->xdisplay,
window->xwindow,
&protocols,
&n_protocols) == Success)
&n_protocols))
{
i = 0;
while (i < n_protocols)
@ -727,6 +803,7 @@ update_wm_hints (MetaWindow *window)
/* Fill in defaults */
window->input = FALSE;
window->initially_iconic = FALSE;
meta_error_trap_push (window->display);
@ -736,8 +813,13 @@ update_wm_hints (MetaWindow *window)
{
window->input = (hints->flags & InputHint) != 0;
window->initially_iconic = (hints->initial_state == IconicState);
/* FIXME there are a few others there. */
meta_verbose ("Read WM_HINTS input: %d iconic: %d\n",
window->input, window->initially_iconic);
XFree (hints);
}

View File

@ -38,7 +38,24 @@ struct _MetaWindow
char *desc; /* used in debug spew */
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;
/* 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 delete_window : 1;
/* Globally active / No input */
@ -63,6 +80,8 @@ MetaWindow* meta_window_new (MetaDisplay *display,
void meta_window_free (MetaWindow *window);
void meta_window_show (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,
int w,
int h);