add override redirect test window

2002-05-10  Havoc Pennington  <hp@pobox.com>

	* src/tools/metacity-window-demo.c: add override redirect test
	window

	* src/stack.c (raise_window_relative_to_managed_windows): new
	function, used to avoid moving windows above override redirect
	popup windows.

	* src/display.c (event_callback): don't lower panels on
	LeaveNotify if they have focus, #70895
This commit is contained in:
Havoc Pennington 2002-05-11 04:44:34 +00:00 committed by Havoc Pennington
parent 2679d3cf00
commit 9598affa03
4 changed files with 134 additions and 6 deletions

View File

@ -1,3 +1,15 @@
2002-05-10 Havoc Pennington <hp@pobox.com>
* src/tools/metacity-window-demo.c: add override redirect test
window
* src/stack.c (raise_window_relative_to_managed_windows): new
function, used to avoid moving windows above override redirect
popup windows.
* src/display.c (event_callback): don't lower panels on
LeaveNotify if they have focus, #70895
2002-05-10 Havoc Pennington <hp@pobox.com>
* src/window.c (constrain_position): when maximizing/fullscreening

View File

@ -1074,7 +1074,8 @@ event_callback (XEvent *event,
if (window->type == META_WINDOW_DOCK &&
event->xcrossing.mode != NotifyGrab &&
event->xcrossing.mode != NotifyUngrab)
event->xcrossing.mode != NotifyUngrab &&
!window->has_focus)
meta_window_lower (window);
}
break;

View File

@ -370,6 +370,98 @@ sort_window_list (GList *list)
return list;
}
static void
raise_window_relative_to_managed_windows (MetaScreen *screen,
Window xwindow)
{
/* This function is used to avoid raising a window above popup
* menus and other such things.
*/
Window ignored1, ignored2;
Window *children;
int n_children;
int i;
/* Normally XQueryTree() means "must grab server" but here
* we don't, since we know we won't manage any new windows
* or restack any windows before using the XQueryTree results.
*/
meta_error_trap_push (screen->display);
XQueryTree (screen->display->xdisplay,
screen->xroot,
&ignored1, &ignored2, &children, &n_children);
if (meta_error_trap_pop (screen->display))
{
meta_topic (META_DEBUG_STACK,
"Error querying root children to raise window 0x%lx\n",
xwindow);
return;
}
/* Children are in order from bottom to top. We want to
* find the topmost managed child, then configure
* our window to be above it.
*/
i = n_children - 1;
while (i >= 0)
{
if (children[i] == xwindow)
{
/* Do nothing. This means we're already the topmost managed
* window, but it DOES NOT mean we are already just above
* the topmost managed window. This is important because if
* an override redirect window is up, and we map a new
* managed window, the new window is probably above the old
* popup by default, and we want to push it below that
* popup. So keep looking for a sibling managed window
* to be moved below.
*/
}
else if (meta_display_lookup_x_window (screen->display,
children[i]) != NULL)
{
XWindowChanges changes;
/* children[i] is the topmost managed child */
meta_topic (META_DEBUG_STACK,
"Moving 0x%lx above topmost managed child window 0x%lx\n",
xwindow, children[i]);
changes.sibling = children[i];
changes.stack_mode = Above;
meta_error_trap_push (screen->display);
XConfigureWindow (screen->display->xdisplay,
xwindow,
CWSibling | CWStackMode,
&changes);
meta_error_trap_pop (screen->display);
break;
}
--i;
}
if (i < 0)
{
/* No sibling to use, just lower ourselves to the bottom
* to be sure we're below any override redirect windows.
*/
meta_error_trap_push (screen->display);
XLowerWindow (screen->display->xdisplay,
xwindow);
meta_error_trap_pop (screen->display);
}
if (children)
XFree (children);
}
static void
meta_stack_sync_to_server (MetaStack *stack)
{
@ -696,10 +788,10 @@ meta_stack_sync_to_server (MetaStack *stack)
/* Move *newp below last_window */
if (last_window == None)
{
meta_topic (META_DEBUG_STACK, "Raising window 0x%lx to the top\n", *newp);
XRaiseWindow (stack->screen->display->xdisplay,
*newp);
meta_topic (META_DEBUG_STACK, "Using window 0x%lx as topmost (but leaving it in-place)\n", *newp);
raise_window_relative_to_managed_windows (stack->screen,
*newp);
}
else
{

View File

@ -310,6 +310,28 @@ menu_cb (gpointer callback_data,
gtk_widget_show_all (window);
}
static void
override_redirect_cb (gpointer callback_data,
guint callback_action,
GtkWidget *widget)
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *label;
window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_title (GTK_WINDOW (window), "Override Redirect");
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
label = gtk_label_new ("This is an override\nredirect window\nand should not be managed");
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show_all (window);
}
static gboolean
focus_in_event_cb (GtkWidget *window,
GdkEvent *event,
@ -522,7 +544,8 @@ static GtkItemFactoryEntry menu_items[] =
{ "/Windows/_All docks", NULL, dock_cb, DOCK_ALL, NULL },
{ "/Windows/Des_ktop", NULL, desktop_cb, 0, NULL },
{ "/Windows/Me_nu", NULL, menu_cb, 0, NULL },
{ "/Windows/Tool_bar", NULL, toolbar_cb, 0, NULL }
{ "/Windows/Tool_bar", NULL, toolbar_cb, 0, NULL },
{ "/Windows/Override Redirect", NULL, override_redirect_cb, 0, NULL }
};
static void