...
This commit is contained in:
parent
1cd2915ba3
commit
ad6efc61b5
@ -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;
|
||||||
|
21
src/frame.c
21
src/frame.c
@ -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
|
||||||
|
92
src/window.c
92
src/window.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
src/window.h
31
src/window.h
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user