...
This commit is contained in:
parent
1cd2915ba3
commit
ad6efc61b5
@ -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)
|
||||
meta_window_free (window); /* Unmanage withdrawn 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;
|
||||
|
21
src/frame.c
21
src/frame.c
@ -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;
|
||||
|
||||
@ -198,9 +198,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);
|
||||
|
||||
@ -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,
|
||||
@ -274,8 +274,9 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
window->rect.y = frame->child_y;
|
||||
|
||||
/* stick frame to the window */
|
||||
window->frame = frame;
|
||||
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
|
||||
|
92
src/window.c
92
src/window.c
@ -121,12 +121,16 @@ 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);
|
||||
|
||||
@ -134,10 +138,24 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
||||
update_title (window);
|
||||
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;
|
||||
}
|
||||
@ -150,6 +168,15 @@ meta_window_free (MetaWindow *window)
|
||||
meta_display_unregister_x_window (window->display, window->xwindow);
|
||||
|
||||
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);
|
||||
@ -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);
|
||||
meta_window_send_icccm_message (window,
|
||||
window->display->atom_wm_delete_window,
|
||||
timestamp);
|
||||
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);
|
||||
|
||||
@ -735,9 +812,14 @@ update_wm_hints (MetaWindow *window)
|
||||
if (hints)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
31
src/window.h
31
src/window.h
@ -37,8 +37,25 @@ struct _MetaWindow
|
||||
Visual *xvisual;
|
||||
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 */
|
||||
@ -58,11 +75,13 @@ struct _MetaWindow
|
||||
XSizeHints size_hints;
|
||||
};
|
||||
|
||||
MetaWindow* meta_window_new (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
void meta_window_free (MetaWindow *window);
|
||||
void meta_window_show (MetaWindow *window);
|
||||
void meta_window_hide (MetaWindow *window);
|
||||
MetaWindow* meta_window_new (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user