Add support for EWMH "Above" and "Below" window states. (105100, Manuel Clos)

This commit is contained in:
Matthias Clasen 2003-08-10 23:37:37 +00:00
parent 19d81dab2b
commit 424433f1a4
17 changed files with 357 additions and 4 deletions

View File

@ -1,5 +1,25 @@
2003-08-11 Matthias Clasen <maclas@gmx.de>
Add support for EWMH "Above" and "Below" window states. (105100, Manuel Clos)
* tests/testgtk.c: Add "Above" and "Below" to the the "Window State" demo.
* gtk/gtkwindow.h: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gtk/gtk.def: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gtk/gtkwindow.c (gtk_window_set_keep_below):
(gtk_window_set_keep_above): New functions, call the corresponding gdk functions.
* gdk/x11/gdkwindow-x11.c (gdk_window_set_keep_below): New function, sets _NET_WM_STATE_BELOW.
(gdk_window_set_keep_above): New function, sets _NET_WM_STATE_ABOVE.
* gdk/gdkwindow.h: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* gdk/gdkevents.h (GdkWindowState): Add GDK_WINDOW_STATE_ABOVE and GDK_WINDOW_STATE_BELOW.
* gdk/gdk.def: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* acinclude.m4: Copy newer versions of JH_CHECK_XML_CATALOG and JH_PATH_XML_CATALOG from
gtk-doc to enable configuring without xmlcatalog in PATH. (#119115)

View File

@ -1,5 +1,25 @@
2003-08-11 Matthias Clasen <maclas@gmx.de>
Add support for EWMH "Above" and "Below" window states. (105100, Manuel Clos)
* tests/testgtk.c: Add "Above" and "Below" to the the "Window State" demo.
* gtk/gtkwindow.h: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gtk/gtk.def: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gtk/gtkwindow.c (gtk_window_set_keep_below):
(gtk_window_set_keep_above): New functions, call the corresponding gdk functions.
* gdk/x11/gdkwindow-x11.c (gdk_window_set_keep_below): New function, sets _NET_WM_STATE_BELOW.
(gdk_window_set_keep_above): New function, sets _NET_WM_STATE_ABOVE.
* gdk/gdkwindow.h: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* gdk/gdkevents.h (GdkWindowState): Add GDK_WINDOW_STATE_ABOVE and GDK_WINDOW_STATE_BELOW.
* gdk/gdk.def: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* acinclude.m4: Copy newer versions of JH_CHECK_XML_CATALOG and JH_PATH_XML_CATALOG from
gtk-doc to enable configuring without xmlcatalog in PATH. (#119115)

View File

@ -1,5 +1,25 @@
2003-08-11 Matthias Clasen <maclas@gmx.de>
Add support for EWMH "Above" and "Below" window states. (105100, Manuel Clos)
* tests/testgtk.c: Add "Above" and "Below" to the the "Window State" demo.
* gtk/gtkwindow.h: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gtk/gtk.def: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gtk/gtkwindow.c (gtk_window_set_keep_below):
(gtk_window_set_keep_above): New functions, call the corresponding gdk functions.
* gdk/x11/gdkwindow-x11.c (gdk_window_set_keep_below): New function, sets _NET_WM_STATE_BELOW.
(gdk_window_set_keep_above): New function, sets _NET_WM_STATE_ABOVE.
* gdk/gdkwindow.h: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* gdk/gdkevents.h (GdkWindowState): Add GDK_WINDOW_STATE_ABOVE and GDK_WINDOW_STATE_BELOW.
* gdk/gdk.def: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* acinclude.m4: Copy newer versions of JH_CHECK_XML_CATALOG and JH_PATH_XML_CATALOG from
gtk-doc to enable configuring without xmlcatalog in PATH. (#119115)

View File

@ -1,5 +1,25 @@
2003-08-11 Matthias Clasen <maclas@gmx.de>
Add support for EWMH "Above" and "Below" window states. (105100, Manuel Clos)
* tests/testgtk.c: Add "Above" and "Below" to the the "Window State" demo.
* gtk/gtkwindow.h: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gtk/gtk.def: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gtk/gtkwindow.c (gtk_window_set_keep_below):
(gtk_window_set_keep_above): New functions, call the corresponding gdk functions.
* gdk/x11/gdkwindow-x11.c (gdk_window_set_keep_below): New function, sets _NET_WM_STATE_BELOW.
(gdk_window_set_keep_above): New function, sets _NET_WM_STATE_ABOVE.
* gdk/gdkwindow.h: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* gdk/gdkevents.h (GdkWindowState): Add GDK_WINDOW_STATE_ABOVE and GDK_WINDOW_STATE_BELOW.
* gdk/gdk.def: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* acinclude.m4: Copy newer versions of JH_CHECK_XML_CATALOG and JH_PATH_XML_CATALOG from
gtk-doc to enable configuring without xmlcatalog in PATH. (#119115)

View File

@ -1,5 +1,25 @@
2003-08-11 Matthias Clasen <maclas@gmx.de>
Add support for EWMH "Above" and "Below" window states. (105100, Manuel Clos)
* tests/testgtk.c: Add "Above" and "Below" to the the "Window State" demo.
* gtk/gtkwindow.h: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gtk/gtk.def: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gtk/gtkwindow.c (gtk_window_set_keep_below):
(gtk_window_set_keep_above): New functions, call the corresponding gdk functions.
* gdk/x11/gdkwindow-x11.c (gdk_window_set_keep_below): New function, sets _NET_WM_STATE_BELOW.
(gdk_window_set_keep_above): New function, sets _NET_WM_STATE_ABOVE.
* gdk/gdkwindow.h: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* gdk/gdkevents.h (GdkWindowState): Add GDK_WINDOW_STATE_ABOVE and GDK_WINDOW_STATE_BELOW.
* gdk/gdk.def: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* acinclude.m4: Copy newer versions of JH_CHECK_XML_CATALOG and JH_PATH_XML_CATALOG from
gtk-doc to enable configuring without xmlcatalog in PATH. (#119115)

View File

@ -1,3 +1,12 @@
2003-08-11 Matthias Clasen <maclas@gmx.de>
* gdk/gdk-sections.txt: Add gdk_window_set_keep_above and gdk_window_set_keep_below.
* gtk/gtk-sections.txt: Add gtk_window_set_keep_above and gtk_window_set_keep_below.
* gdk/tmpl/event_structs.sgml: Document GDK_WINDOW_STATE_FULLSCREEN,
GDK_WINDOW_STATE_ABOVE and GDK_WINDOW_STATE_BELOW.
2003-08-10 Matthias Clasen <maclas@gmx.de>
* gtk/tmpl/gtkwidget.sgml: Document public GtkWidget members. (#119463)

View File

@ -614,6 +614,8 @@ gdk_window_maximize
gdk_window_unmaximize
gdk_window_fullscreen
gdk_window_unfullscreen
gdk_window_set_keep_above
gdk_window_set_keep_below
gdk_window_move
gdk_window_resize
gdk_window_move_resize

View File

@ -471,7 +471,9 @@ Specifies the state of a toplevel window.
@GDK_WINDOW_STATE_ICONIFIED: the window is minimized.
@GDK_WINDOW_STATE_MAXIMIZED: the window is maximized.
@GDK_WINDOW_STATE_STICKY: the window is sticky.
@GDK_WINDOW_STATE_FULLSCREEN:
@GDK_WINDOW_STATE_FULLSCREEN: the window is maximized without decorations.
@GDK_WINDOW_STATE_ABOVE: the window is kept above other windows.
@GDK_WINDOW_STATE_BELOW: the window is kept below other windows.
<!-- ##### ENUM GdkSettingAction ##### -->
<para>

View File

@ -3952,6 +3952,8 @@ gtk_window_maximize
gtk_window_unmaximize
gtk_window_fullscreen
gtk_window_unfullscreen
gtk_window_set_keep_above
gtk_window_set_keep_below
gtk_window_begin_resize_drag
gtk_window_begin_move_drag
gtk_window_set_decorated

View File

@ -521,6 +521,8 @@ EXPORTS
gdk_window_set_icon
gdk_window_set_icon_list
gdk_window_set_icon_name
gdk_window_set_keep_above
gdk_window_set_keep_below
gdk_window_set_modal_hint
gdk_window_set_override_redirect
gdk_window_set_role

View File

@ -207,7 +207,9 @@ typedef enum
GDK_WINDOW_STATE_ICONIFIED = 1 << 1,
GDK_WINDOW_STATE_MAXIMIZED = 1 << 2,
GDK_WINDOW_STATE_STICKY = 1 << 3,
GDK_WINDOW_STATE_FULLSCREEN = 1 << 4
GDK_WINDOW_STATE_FULLSCREEN = 1 << 4,
GDK_WINDOW_STATE_ABOVE = 1 << 5,
GDK_WINDOW_STATE_BELOW = 1 << 6
} GdkWindowState;
typedef enum

View File

@ -502,6 +502,10 @@ void gdk_window_maximize (GdkWindow *window);
void gdk_window_unmaximize (GdkWindow *window);
void gdk_window_fullscreen (GdkWindow *window);
void gdk_window_unfullscreen (GdkWindow *window);
void gdk_window_set_keep_above (GdkWindow *window,
gboolean setting);
void gdk_window_set_keep_below (GdkWindow *window,
gboolean setting);
void gdk_window_register_dnd (GdkWindow *window);

View File

@ -3792,6 +3792,77 @@ gdk_window_unfullscreen (GdkWindow *window)
0);
}
/**
* gdk_window_set_keep_above:
* @window: a toplevel #GdkWindow
* @setting: whether to keep @window above other windows
*
* Set if @window must be kept above other windows. If the
* window was already above, then this function does nothing.
*
* On X11, asks the window manager to keep @window above, if the window
* manager supports this operation. Not all window managers support
* this, and some deliberately ignore it or don't have a concept of
* "keep above"; so you can't rely on the window being kept above.
* But it will happen with most standard window managers,
* and GDK makes a best effort to get it to happen.
*
* Since: 2.4
**/
void
gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
{
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
if (GDK_WINDOW_IS_MAPPED (window))
gdk_wmspec_change_state (setting, window,
gdk_atom_intern ("_NET_WM_STATE_ABOVE", setting),
setting ? gdk_atom_intern ("_NET_WM_STATE_BELOW", FALSE)
: GDK_NONE);
else
gdk_synthesize_window_state (window,
setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
setting ? GDK_WINDOW_STATE_ABOVE : 0);
}
/**
* gdk_window_set_keep_below:
* @window: a toplevel #GdkWindow
* @setting: whether to keep @window below other windows
*
* Set if @window must be kept below other windows. If the
* window was already below, then this function does nothing.
*
* On X11, asks the window manager to keep @window below, if the window
* manager supports this operation. Not all window managers support
* this, and some deliberately ignore it or don't have a concept of
* "keep below"; so you can't rely on the window being kept below.
* But it will happen with most standard window managers,
* and GDK makes a best effort to get it to happen.
*
* Since: 2.4
**/
void
gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
{
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
if (GDK_WINDOW_IS_MAPPED (window))
gdk_wmspec_change_state (setting, window,
gdk_atom_intern ("_NET_WM_STATE_BELOW", setting),
setting ? gdk_atom_intern ("_NET_WM_STATE_ABOVE", FALSE)
: GDK_NONE);
else
gdk_synthesize_window_state (window,
setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
setting ? GDK_WINDOW_STATE_BELOW : 0);
}
/**
* gdk_window_set_group:

View File

@ -2367,6 +2367,8 @@ EXPORTS
gtk_window_set_icon
gtk_window_set_icon_from_file
gtk_window_set_icon_list
gtk_window_set_keep_above
gtk_window_set_keep_below
gtk_window_set_mnemonic_modifier
gtk_window_set_modal
gtk_window_set_policy

View File

@ -3185,7 +3185,7 @@ gtk_window_get_size (GtkWindow *window,
* <literal>gtk_window_move (window, gdk_screen_width () - window_width,
* gdk_screen_height () - window_height)</literal>.
*
* The extended window manager hints specification at <ulink
* The Extended Window Manager Hints specification at <ulink
* url="http://www.freedesktop.org/standards/wm-spec.html">
* http://www.freedesktop.org/standards/wm-spec.html</ulink> has a
* nice table of gravities in the "implementation notes" section.
@ -3671,6 +3671,10 @@ gtk_window_map (GtkWidget *widget)
else
gdk_window_unfullscreen (toplevel);
gdk_window_set_keep_above (toplevel, window->above_initially);
gdk_window_set_keep_below (toplevel, window->below_initially);
/* No longer use the default settings */
window->need_default_size = FALSE;
window->need_default_position = FALSE;
@ -3721,6 +3725,8 @@ gtk_window_unmap (GtkWidget *widget)
window->iconify_initially = state & GDK_WINDOW_STATE_ICONIFIED;
window->maximize_initially = state & GDK_WINDOW_STATE_MAXIMIZED;
window->stick_initially = state & GDK_WINDOW_STATE_STICKY;
window->above_initially = state & GDK_WINDOW_STATE_ABOVE;
window->below_initially = state & GDK_WINDOW_STATE_BELOW;
}
static void
@ -5943,6 +5949,105 @@ gtk_window_unfullscreen (GtkWindow *window)
gdk_window_unfullscreen (toplevel);
}
/**
* gtk_window_set_keep_above:
* @window: a #GtkWindow
* @setting: whether to keep @window above other windows
*
* Asks to keep @window above, so that it stays on top. Note that
* you shouldn't assume the window is definitely above afterward,
* because other entities (e.g. the user or <link
* linkend="gtk-X11-arch">window manager</link>) could not keep it above,
* and not all window managers support keeping windows above. But
* normally the window will end kept above. Just don't write code
* that crashes if not.
*
* It's permitted to call this function before showing a window,
* in which case the window will be kept above when it appears onscreen
* initially.
*
* You can track the above state via the "window_state_event" signal
* on #GtkWidget.
*
* Note that, according to the <ulink
* url="http://www.freedesktop.org/standards/wm-spec.html">Extended Window Manager Hints</ulink>
* specification, the above state is mainly meant for user preferences and should not be used
* by applications e.g. for drawing attention to their dialogs.
*
* Since: 2.4
**/
void
gtk_window_set_keep_above (GtkWindow *window, gboolean setting)
{
GtkWidget *widget;
GdkWindow *toplevel;
g_return_if_fail (GTK_IS_WINDOW (window));
widget = GTK_WIDGET (window);
window->above_initially = setting;
if (setting)
window->below_initially = FALSE;
if (window->frame)
toplevel = window->frame;
else
toplevel = widget->window;
if (toplevel != NULL)
gdk_window_set_keep_above (toplevel, setting);
}
/**
* gtk_window_set_keep_below:
* @window: a #GtkWindow
* @setting: whether to keep @window below other windows
*
* Asks to keep @window below, so that it stays in bottom. Note that
* you shouldn't assume the window is definitely below afterward,
* because other entities (e.g. the user or <link
* linkend="gtk-X11-arch">window manager</link>) could not keep it below,
* and not all window managers support putting windows below. But
* normally the window will be kept below. Just don't write code
* that crashes if not.
*
* It's permitted to call this function before showing a window,
* in which case the window will be kept below when it appears onscreen
* initially.
*
* You can track the below state via the "window_state_event" signal
* on #GtkWidget.
*
* Note that, according to the <ulink
* url="http://www.freedesktop.org/standards/wm-spec.html">Extended Window Manager Hints</ulink>
* specification, the above state is mainly meant for user preferences and should not be used
* by applications e.g. for drawing attention to their dialogs.
*
* Since: 2.4
**/
void
gtk_window_set_keep_below (GtkWindow *window, gboolean setting)
{
GtkWidget *widget;
GdkWindow *toplevel;
g_return_if_fail (GTK_IS_WINDOW (window));
widget = GTK_WIDGET (window);
window->below_initially = setting;
if (setting)
window->above_initially = FALSE;
if (window->frame)
toplevel = window->frame;
else
toplevel = widget->window;
if (toplevel != NULL)
gdk_window_set_keep_below (toplevel, setting);
}
/**
* gtk_window_set_resizable:

View File

@ -96,6 +96,8 @@ struct _GtkWindow
guint stick_initially : 1;
guint maximize_initially : 1;
guint decorated : 1;
guint above_initially : 1;
guint below_initially : 1;
guint type_hint : 3; /* GdkWindowTypeHint */
guint gravity : 5; /* GdkGravity */
@ -286,6 +288,8 @@ void gtk_window_maximize (GtkWindow *window);
void gtk_window_unmaximize (GtkWindow *window);
void gtk_window_fullscreen (GtkWindow *window);
void gtk_window_unfullscreen (GtkWindow *window);
void gtk_window_set_keep_above (GtkWindow *window, gboolean setting);
void gtk_window_set_keep_below (GtkWindow *window, gboolean setting);
void gtk_window_begin_resize_drag (GtkWindow *window,
GdkWindowEdge edge,

View File

@ -9436,6 +9436,10 @@ window_state_callback (GtkWidget *widget,
"maximized" : "not maximized", ", ",
(event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
"fullscreen" : "not fullscreen",
(event->new_window_state & GDK_WINDOW_STATE_ABOVE) ?
"above" : "not above", ", ",
(event->new_window_state & GDK_WINDOW_STATE_BELOW) ?
"below" : "not below", ", ",
NULL);
gtk_label_set_text (GTK_LABEL (label), msg);
@ -9522,11 +9526,38 @@ tracking_label (GtkWidget *window)
return hbox;
}
void
keep_window_above (GtkToggleButton *togglebutton, gpointer data)
{
GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
gtk_window_set_keep_above (GTK_WINDOW (data),
gtk_toggle_button_get_active (togglebutton));
if (gtk_toggle_button_get_active (togglebutton))
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
}
void
keep_window_below (GtkToggleButton *togglebutton, gpointer data)
{
GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
gtk_window_set_keep_below (GTK_WINDOW (data),
gtk_toggle_button_get_active (togglebutton));
if (gtk_toggle_button_get_active (togglebutton))
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
}
static GtkWidget*
get_state_controls (GtkWidget *window)
{
GtkWidget *vbox;
GtkWidget *button;
GtkWidget *button_above;
GtkWidget *button_below;
vbox = gtk_vbox_new (FALSE, 0);
@ -9585,7 +9616,24 @@ get_state_controls (GtkWidget *window)
window,
G_CONNECT_SWAPPED);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
button_above = gtk_toggle_button_new_with_label ("Keep above");
g_signal_connect (button_above,
"toggled",
G_CALLBACK (keep_window_above),
window);
gtk_box_pack_start (GTK_BOX (vbox), button_above, FALSE, FALSE, 0);
button_below = gtk_toggle_button_new_with_label ("Keep below");
g_signal_connect (button_below,
"toggled",
G_CALLBACK (keep_window_below),
window);
gtk_box_pack_start (GTK_BOX (vbox), button_below, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (button_above), "radio", button_below);
g_object_set_data (G_OBJECT (button_below), "radio", button_above);
button = gtk_button_new_with_label ("Hide (withdraw)");
g_signal_connect_object (button,
"clicked",