g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
g_signal_handlers_disconnect_by_func (accel_group,
- (gpointer) gtk_window_notify_keys_changed,
+ gtk_window_notify_keys_changed,
window);
_gtk_accel_group_detach (accel_group, G_OBJECT (window));
}
g_object_set_data_full (G_OBJECT (window), "gtk-embedded",
embedded_windows,
embedded_windows ?
- (GtkDestroyNotify) g_list_free : NULL);
+ (GDestroyNotify) g_list_free : NULL);
}
void
g_object_set_data_full (G_OBJECT (window), "gtk-embedded",
embedded_windows,
embedded_windows ?
- (GtkDestroyNotify) g_list_free : NULL);
+ (GDestroyNotify) g_list_free : NULL);
}
void
if (window->transient_parent)
{
g_signal_handlers_disconnect_by_func (window->transient_parent,
- G_CALLBACK (parent_destroyed_callback),
+ parent_destroyed_callback,
window);
}
}
gdk_atom_intern ("WM_TRANSIENT_FOR", FALSE));
}
+static void
+gtk_window_transient_parent_screen_changed (GtkWindow *parent,
+ GParamSpec *pspec,
+ GtkWindow *window)
+{
+ gtk_window_set_screen (window, parent->screen);
+}
+
static void
gtk_window_unset_transient_for (GtkWindow *window)
{
if (window->transient_parent)
{
g_signal_handlers_disconnect_by_func (window->transient_parent,
- G_CALLBACK (gtk_window_transient_parent_realized),
+ gtk_window_transient_parent_realized,
window);
g_signal_handlers_disconnect_by_func (window->transient_parent,
- G_CALLBACK (gtk_window_transient_parent_unrealized),
+ gtk_window_transient_parent_unrealized,
window);
g_signal_handlers_disconnect_by_func (window->transient_parent,
- G_CALLBACK (gtk_widget_destroyed),
+ gtk_window_transient_parent_screen_changed,
+ window);
+ g_signal_handlers_disconnect_by_func (window->transient_parent,
+ gtk_widget_destroyed,
&window->transient_parent);
if (window->destroy_with_parent)
g_signal_connect (parent, "unrealize",
G_CALLBACK (gtk_window_transient_parent_unrealized),
window);
+ g_signal_connect (parent, "notify::screen",
+ G_CALLBACK (gtk_window_transient_parent_screen_changed),
+ window);
- window->screen = parent->screen;
+ gtk_window_set_screen (window, parent->screen);
if (window->destroy_with_parent)
connect_parent_destroyed (window);
if (info->widget)
g_signal_handlers_disconnect_by_func (info->widget,
- G_CALLBACK (gtk_widget_destroyed),
+ gtk_widget_destroyed,
&info->widget);
info->widget = geometry_widget;
* managers</link> allow GTK+ to disable these decorations, creating a
* borderless window. If you set the decorated property to %FALSE
* using this function, GTK+ will do its best to convince the window
- * manager not to decorate the window.
+ * manager not to decorate the window. Depending on the system, this
+ * function may not have any effect when called on a window that is
+ * already visible, so you should call it before calling gtk_window_show().
*
* On Windows, this function always works, since there's no window manager
* policy involved.
/**
* gtk_window_set_icon_from_file:
* @window: a #GtkWindow
- * @list: a list of #GdkPixbuf
+ * @filename: location of icon file
* @err: location to store error, or %NULL.
*
- * Sets the icon for @wi
- * had gtk_window_set_icon_list() called on them as a single file.
+ * Sets the icon for @window.
* Warns on failure if @err is %NULL.
*
+ * This function is equivalent to calling gtk_window_set_icon()
+ * with a pixbuf created by loading the image from @filename.
+ *
* Returns: %TRUE if setting the icon succeeded.
**/
gboolean
*
* Sets an icon to be used as fallback for windows that haven't
* had gtk_window_set_icon_list() called on them from a file
- * on disk. Warns on failure if @error is %NULL.
+ * on disk. Warns on failure if @err is %NULL.
*
* Returns: %TRUE if setting the icon succeeded.
**/
{
if (window->geometry_info->widget)
g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
- G_CALLBACK (gtk_widget_destroyed),
+ gtk_widget_destroyed,
&window->geometry_info->widget);
g_free (window->geometry_info);
}
return pos;
}
+static int
+get_center_monitor_of_window (GtkWindow *window)
+{
+ /* We could try to sort out the relative positions of the monitors and
+ * stuff, or we could just be losers and assume you have a row
+ * or column of monitors.
+ */
+ return gdk_screen_get_n_monitors (window->screen) / 2;
+}
+
+static int
+get_monitor_containing_pointer (GtkWindow *window)
+{
+ gint px, py;
+ gint monitor_num;
+ GdkScreen *pointer_screen;
+
+ gdk_display_get_pointer (gdk_screen_get_display (window->screen),
+ &pointer_screen,
+ &px, &py, NULL);
+
+ if (pointer_screen == window->screen)
+ monitor_num = gdk_screen_get_monitor_at_point (window->screen, px, py);
+ else
+ monitor_num = -1;
+
+ return monitor_num;
+}
+
+static void
+center_window_on_monitor (GtkWindow *window,
+ gint w,
+ gint h,
+ gint *x,
+ gint *y)
+{
+ GdkRectangle monitor;
+ int monitor_num;
+
+ monitor_num = get_monitor_containing_pointer (window);
+
+ if (monitor_num == -1)
+ monitor_num = get_center_monitor_of_window (window);
+
+ gdk_screen_get_monitor_geometry (window->screen, monitor_num, &monitor);
+
+ *x = (monitor.width - w) / 2 + monitor.x;
+ *y = (monitor.height - h) / 2 + monitor.y;
+
+ /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
+ * and WM decorations.
+ */
+ if (*x < monitor.x)
+ *x = monitor.x;
+ if (*y < monitor.y)
+ *y = monitor.y;
+}
+
+static void
+clamp_window_to_rectangle (gint *x,
+ gint *y,
+ gint w,
+ gint h,
+ const GdkRectangle *rect)
+{
+ gint outside_w, outside_h;
+
+ outside_w = (*x + w) - (rect->x + rect->width);
+ if (outside_w > 0)
+ *x -= outside_w;
+
+ outside_h = (*y + h) - (rect->y + rect->height);
+ if (outside_h > 0)
+ *y -= outside_h;
+
+ /* if larger than the screen, center on the screen. */
+ if (*x < rect->x)
+ *x += (rect->x - *x) / 2;
+ if (*y < rect->y)
+ *y += (rect->y - *y) / 2;
+}
+
+
static void
gtk_window_compute_configure_request (GtkWindow *window,
GdkRectangle *request,
*/
case GTK_WIN_POS_CENTER_ALWAYS:
case GTK_WIN_POS_CENTER:
- {
- gint px, py, monitor_num;
- GdkRectangle monitor;
-
- gdk_window_get_pointer (gdk_screen_get_root_window (window->screen),
- &px, &py, NULL);
-
- monitor_num = gdk_screen_get_monitor_at_point (window->screen, px, py);
- if (monitor_num == -1)
- monitor_num = 0;
-
- gdk_screen_get_monitor_geometry (window->screen, monitor_num, &monitor);
-
- x = (monitor.width - w) / 2 + monitor.x;
- y = (monitor.height - h) / 2 + monitor.y;
- }
+ center_window_on_monitor (window, w, h, &x, &y);
break;
case GTK_WIN_POS_CENTER_ON_PARENT:
{
+ gint monitor_num;
+ GdkRectangle monitor;
gint ox, oy;
g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
+
+ if (parent_widget->window != NULL)
+ monitor_num = gdk_screen_get_monitor_at_window (window->screen,
+ parent_widget->window);
+ else
+ monitor_num = -1;
gdk_window_get_origin (parent_widget->window,
&ox, &oy);
x = ox + (parent_widget->allocation.width - w) / 2;
y = oy + (parent_widget->allocation.height - h) / 2;
+
+ /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
+ * WM decorations. If parent wasn't on a monitor, just
+ * give up.
+ */
+ if (monitor_num >= 0)
+ {
+ gdk_screen_get_monitor_geometry (window->screen, monitor_num, &monitor);
+ clamp_window_to_rectangle (&x, &y, w, h, &monitor);
+ }
}
break;
{
gint screen_width = gdk_screen_get_width (window->screen);
gint screen_height = gdk_screen_get_height (window->screen);
- int px, py;
+ gint monitor_num;
+ GdkRectangle monitor;
+ GdkScreen *pointer_screen;
+ gint px, py;
+
+ gdk_display_get_pointer (gdk_screen_get_display (window->screen),
+ &pointer_screen,
+ &px, &py, NULL);
+
+ if (pointer_screen == window->screen)
+ monitor_num = gdk_screen_get_monitor_at_point (window->screen, px, py);
+ else
+ monitor_num = -1;
- gdk_window_get_pointer (gdk_screen_get_root_window (window->screen),
- &px, &py, NULL);
x = px - w / 2;
y = py - h / 2;
x = CLAMP (x, 0, screen_width - w);
y = CLAMP (y, 0, screen_height - h);
+
+ /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
+ * WM decorations. Don't try to figure out what's going
+ * on if the mouse wasn't inside a monitor.
+ */
+ if (monitor_num >= 0)
+ {
+ gdk_screen_get_monitor_geometry (window->screen, monitor_num, &monitor);
+ clamp_window_to_rectangle (&x, &y, w, h, &monitor);
+ }
}
break;
if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
{
gint center_x, center_y;
- gint screen_width = gdk_screen_get_width (window->screen);
- gint screen_height = gdk_screen_get_height (window->screen);
-
- center_x = (screen_width - new_width) / 2;
- center_y = (screen_height - new_height) / 2;
+
+ center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
*x = center_x;
*y = center_y;