diff options
author | Jeremy Whiting <jpwhiting@kde.org> | 2015-07-13 10:30:42 -0600 |
---|---|---|
committer | Jeremy Whiting <jpwhiting@kde.org> | 2015-07-25 07:08:59 -0600 |
commit | f9d903995dda32674f8297e8496dc6846e220c88 (patch) | |
tree | 6c38df4a179ff839f7e3894964eaff2f4b67c887 | |
parent | 2a2a1487d9bfd43606e34ba2294f708e6df067d9 (diff) | |
download | gtk+-f9d903995dda32674f8297e8496dc6846e220c88.tar.gz |
Added api to set a window to fullscreen on a given monitor.
https://bugzilla.gnome.org/show_bug.cgi?id=752677
-rw-r--r-- | gdk/gdkwindow.c | 26 | ||||
-rw-r--r-- | gdk/gdkwindow.h | 3 | ||||
-rw-r--r-- | gdk/gdkwindowimpl.h | 1 | ||||
-rw-r--r-- | gdk/wayland/gdkprivate-wayland.h | 2 | ||||
-rw-r--r-- | gdk/wayland/gdkscreen-wayland.c | 9 | ||||
-rw-r--r-- | gdk/wayland/gdkwindow-wayland.c | 35 | ||||
-rw-r--r-- | gtk/gtkwindow.c | 62 | ||||
-rw-r--r-- | gtk/gtkwindow.h | 4 |
8 files changed, 139 insertions, 3 deletions
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index f6516e5130..18ba8ac8af 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -10298,6 +10298,32 @@ gdk_window_fullscreen (GdkWindow *window) } /** + * gdk_window_fullscreen_on_monitor: + * @window: a toplevel #GdkWindow + * @monitor: Which monitor to display fullscreen on. + * + * Moves the window into fullscreen mode on the given monitor. This means + * the window covers the entire screen and is above any panels or task bars. + * + * If the window was already fullscreen, then this function does nothing. + * Since: UNRELEASED + **/ +void +gdk_window_fullscreen_on_monitor (GdkWindow *window, + gint monitor) +{ + GdkScreen *screen = gdk_window_get_screen (window); + + g_return_if_fail (monitor >= 0); + g_return_if_fail (monitor < gdk_screen_get_n_monitors (screen)); + + if (GDK_WINDOW_IMPL_GET_CLASS (window->impl)->fullscreen_on_monitor != NULL) + GDK_WINDOW_IMPL_GET_CLASS (window->impl)->fullscreen_on_monitor (window, monitor); + else + GDK_WINDOW_IMPL_GET_CLASS (window->impl)->fullscreen (window); +} + +/** * gdk_window_set_fullscreen_mode: * @window: a toplevel #GdkWindow * @mode: fullscreen mode diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h index 98c59b8f35..7eee68464f 100644 --- a/gdk/gdkwindow.h +++ b/gdk/gdkwindow.h @@ -952,6 +952,9 @@ GDK_AVAILABLE_IN_ALL void gdk_window_unmaximize (GdkWindow *window); GDK_AVAILABLE_IN_ALL void gdk_window_fullscreen (GdkWindow *window); +GDK_AVAILABLE_IN_3_18 +void gdk_window_fullscreen_on_monitor (GdkWindow *window, + gint monitor); GDK_AVAILABLE_IN_3_8 void gdk_window_set_fullscreen_mode (GdkWindow *window, GdkFullscreenMode mode); diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h index 73a819a8f2..07a307c269 100644 --- a/gdk/gdkwindowimpl.h +++ b/gdk/gdkwindowimpl.h @@ -198,6 +198,7 @@ struct _GdkWindowImplClass void (* maximize) (GdkWindow *window); void (* unmaximize) (GdkWindow *window); void (* fullscreen) (GdkWindow *window); + void (* fullscreen_on_monitor) (GdkWindow *window, gint monitor); void (* apply_fullscreen_mode) (GdkWindow *window); void (* unfullscreen) (GdkWindow *window); void (* set_keep_above) (GdkWindow *window, diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index cd36c2e4e1..5f8f37d12d 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -213,6 +213,8 @@ int _gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen, struct wl_output *output); guint32 _gdk_wayland_screen_get_output_scale (GdkScreen *screen, struct wl_output *output); +struct wl_output *_gdk_wayland_screen_get_wl_output (GdkScreen *screen, + gint monitor_num); void _gdk_wayland_screen_set_has_gtk_shell (GdkScreen *screen); diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c index a2740871af..b07483bc69 100644 --- a/gdk/wayland/gdkscreen-wayland.c +++ b/gdk/wayland/gdkscreen-wayland.c @@ -1143,6 +1143,15 @@ _gdk_wayland_screen_add_output (GdkScreen *screen, wl_output_add_listener (output, &output_listener, monitor); } +struct wl_output * +_gdk_wayland_screen_get_wl_output (GdkScreen *screen, + gint monitor_num) +{ + GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen); + GdkWaylandMonitor *monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num); + return monitor->output; +} + void _gdk_wayland_screen_remove_output (GdkScreen *screen, guint32 id) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index d5880b6e25..e9d077e00e 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -141,6 +141,8 @@ struct _GdkWindowImplWayland int margin_right; int margin_top; int margin_bottom; + + int initial_fullscreen_monitor; cairo_region_t *opaque_region; cairo_region_t *input_region; @@ -168,6 +170,7 @@ static void _gdk_window_impl_wayland_init (GdkWindowImplWayland *impl) { impl->scale = 1; + impl->initial_fullscreen_monitor = -1; } /* @@ -996,6 +999,10 @@ gdk_wayland_window_create_xdg_surface (GdkWindow *window) GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); const gchar *app_id; + GdkScreen *screen = gdk_window_get_screen (window); + struct wl_output *fullscreen_output = NULL; + if (impl->initial_fullscreen_monitor < gdk_screen_get_n_monitors (screen)) + fullscreen_output = _gdk_wayland_screen_get_wl_output (screen, impl->initial_fullscreen_monitor); impl->xdg_surface = xdg_shell_get_xdg_surface (display_wayland->xdg_shell, impl->surface); xdg_surface_add_listener (impl->xdg_surface, &xdg_surface_listener, window); @@ -1007,7 +1014,7 @@ gdk_wayland_window_create_xdg_surface (GdkWindow *window) if (window->state & GDK_WINDOW_STATE_MAXIMIZED) xdg_surface_set_maximized (impl->xdg_surface); if (window->state & GDK_WINDOW_STATE_FULLSCREEN) - xdg_surface_set_fullscreen (impl->xdg_surface, NULL); + xdg_surface_set_fullscreen (impl->xdg_surface, fullscreen_output); app_id = impl->application.application_id; if (app_id == NULL) @@ -1898,6 +1905,25 @@ gdk_wayland_window_unmaximize (GdkWindow *window) } static void +gdk_wayland_window_fullscreen_on_monitor (GdkWindow *window, gint monitor) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + GdkScreen *screen = gdk_window_get_screen (window); + struct wl_output *fullscreen_output = + _gdk_wayland_screen_get_wl_output (screen, monitor); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (impl->xdg_surface) + xdg_surface_set_fullscreen (impl->xdg_surface, fullscreen_output); + else { + gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN); + impl->initial_fullscreen_monitor = monitor; + } +} + +static void gdk_wayland_window_fullscreen (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); @@ -1905,6 +1931,8 @@ gdk_wayland_window_fullscreen (GdkWindow *window) if (GDK_WINDOW_DESTROYED (window)) return; + impl->initial_fullscreen_monitor = -1; + if (impl->xdg_surface) xdg_surface_set_fullscreen (impl->xdg_surface, NULL); else @@ -1915,10 +1943,12 @@ static void gdk_wayland_window_unfullscreen (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); - + if (GDK_WINDOW_DESTROYED (window)) return; + impl->initial_fullscreen_monitor = -1; + if (impl->xdg_surface) xdg_surface_unset_fullscreen (impl->xdg_surface); else @@ -2316,6 +2346,7 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass) impl_class->maximize = gdk_wayland_window_maximize; impl_class->unmaximize = gdk_wayland_window_unmaximize; impl_class->fullscreen = gdk_wayland_window_fullscreen; + impl_class->fullscreen_on_monitor = gdk_wayland_window_fullscreen_on_monitor; impl_class->unfullscreen = gdk_wayland_window_unfullscreen; impl_class->set_keep_above = gdk_wayland_window_set_keep_above; impl_class->set_keep_below = gdk_wayland_window_set_keep_below; diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 4b45a0dac6..0b53cd4f6a 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -187,6 +187,7 @@ struct _GtkWindowPrivate GtkWidget *popup_menu; GdkWindow *border_window[8]; + gint initial_fullscreen_monitor; /* The following flags are initially TRUE (before a window is mapped). * They cause us to compute a configure request that involves @@ -1642,6 +1643,7 @@ gtk_window_init (GtkWindow *window) priv->initial_timestamp = GDK_CURRENT_TIME; priv->mnemonics_visible = TRUE; priv->focus_visible = TRUE; + priv->initial_fullscreen_monitor = -1; g_object_ref_sink (window); priv->has_user_ref_count = TRUE; @@ -6060,6 +6062,7 @@ gtk_window_map (GtkWidget *widget) GtkWindowPrivate *priv = window->priv; GdkWindow *gdk_window; GList *link; + GdkScreen *screen; if (!gtk_widget_is_toplevel (widget)) { @@ -6067,6 +6070,10 @@ gtk_window_map (GtkWidget *widget) return; } + screen = gtk_window_get_screen (widget); + if (priv->initial_fullscreen_monitor > gdk_screen_get_n_monitors (screen)) + priv->initial_fullscreen_monitor = -1; + gtk_widget_set_mapped (widget, TRUE); child = gtk_bin_get_child (&(window->bin)); @@ -6096,7 +6103,13 @@ gtk_window_map (GtkWidget *widget) gdk_window_deiconify (gdk_window); if (priv->fullscreen_initially) - gdk_window_fullscreen (gdk_window); + { + if (priv->initial_fullscreen_monitor < 0) + gdk_window_fullscreen (gdk_window); + else + gdk_window_fullscreen_on_monitor (gdk_window, + priv->initial_fullscreen_monitor); + } else gdk_window_unfullscreen (gdk_window); @@ -10162,6 +10175,48 @@ gtk_window_fullscreen (GtkWindow *window) } /** + * gtk_window_fullscreen_on_monitor: + * @window: a #GtkWindow + * @screen: a #GdkScreen to draw to + * @monitor: which monitor to go fullscreen on + * + * Asks to place @window in the fullscreen state. Note that you shouldn't assume + * the window is definitely full screen afterward. + * + * You can track the fullscreen state via the "window-state-event" signal + * on #GtkWidget. + * + * Since: 3.18 + */ +void +gtk_window_fullscreen_on_monitor (GtkWindow *window, + GdkScreen *screen, + gint monitor) +{ + GtkWindowPrivate *priv; + GtkWidget *widget; + GdkWindow *toplevel; + + g_return_if_fail (GTK_IS_WINDOW (window)); + g_return_if_fail (GDK_IS_SCREEN (screen)); + g_return_if_fail (monitor >= 0); + g_return_if_fail (monitor < gdk_screen_get_n_monitors (screen)); + + priv = window->priv; + widget = GTK_WIDGET (window); + + gtk_window_set_screen (window, screen); + + priv->initial_fullscreen_monitor = monitor; + priv->fullscreen_initially = TRUE; + + toplevel = gtk_widget_get_window (widget); + + if (toplevel != NULL) + gdk_window_fullscreen_on_monitor (toplevel, monitor); +} + +/** * gtk_window_unfullscreen: * @window: a #GtkWindow * @@ -10188,6 +10243,8 @@ gtk_window_unfullscreen (GtkWindow *window) window->priv->fullscreen_initially = FALSE; toplevel = gtk_widget_get_window (GTK_WIDGET (window)); + window->priv->fullscreen_initially = FALSE; + window->priv->initial_fullscreen_monitor = -1; if (toplevel != NULL) gdk_window_unfullscreen (toplevel); @@ -10491,6 +10548,9 @@ gtk_window_set_screen (GtkWindow *window, if (screen == priv->screen) return; + /* reset initial_fullscreen_monitor since they are relative to the screen */ + priv->initial_fullscreen_monitor = -1; + widget = GTK_WIDGET (window); previous_screen = priv->screen; diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h index b40efdc875..bd73697f38 100644 --- a/gtk/gtkwindow.h +++ b/gtk/gtkwindow.h @@ -387,6 +387,10 @@ GDK_AVAILABLE_IN_ALL void gtk_window_fullscreen (GtkWindow *window); GDK_AVAILABLE_IN_ALL void gtk_window_unfullscreen (GtkWindow *window); +GDK_AVAILABLE_IN_3_18 +void gtk_window_fullscreen_on_monitor(GtkWindow *window, + GdkScreen *screen, + gint monitor); GDK_AVAILABLE_IN_3_10 void gtk_window_close (GtkWindow *window); GDK_AVAILABLE_IN_ALL |