зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1160014 part 6 - Implement fullscreen transition for GTK. r=roc
--HG-- extra : source : ae8bf45b7efcd297ad92039b5ea6985dbfa725e9
This commit is contained in:
Родитель
76b36e0a05
Коммит
7ec583cc8f
|
@ -61,6 +61,7 @@ STUB(gdk_screen_get_resolution)
|
|||
STUB(gdk_screen_get_rgba_visual)
|
||||
STUB(gdk_screen_get_root_window)
|
||||
STUB(gdk_screen_get_system_visual)
|
||||
STUB(gdk_screen_get_width)
|
||||
STUB(gdk_screen_height)
|
||||
STUB(gdk_screen_is_composited)
|
||||
STUB(gdk_screen_width)
|
||||
|
@ -437,11 +438,14 @@ STUB(gtk_widget_hide)
|
|||
STUB(gtk_widget_is_focus)
|
||||
STUB(gtk_widget_is_toplevel)
|
||||
STUB(gtk_widget_map)
|
||||
STUB(gtk_widget_modify_bg)
|
||||
STUB(gtk_widget_realize)
|
||||
STUB(gtk_widget_reparent)
|
||||
STUB(gtk_widget_set_allocation)
|
||||
STUB(gtk_widget_set_app_paintable)
|
||||
STUB(gtk_window_set_auto_startup_notification)
|
||||
STUB(gtk_window_set_opacity)
|
||||
STUB(gtk_window_set_screen)
|
||||
STUB(gtk_widget_set_can_focus)
|
||||
STUB(gtk_widget_set_direction)
|
||||
STUB(gtk_widget_set_double_buffered)
|
||||
|
|
|
@ -4611,6 +4611,117 @@ nsWindow::ConvertBorderStyles(nsBorderStyle aStyle)
|
|||
return w;
|
||||
}
|
||||
|
||||
class FullscreenTransitionWindow final : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit FullscreenTransitionWindow(GtkWidget* aWidget);
|
||||
|
||||
GtkWidget* mWindow;
|
||||
|
||||
private:
|
||||
~FullscreenTransitionWindow();
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS0(FullscreenTransitionWindow)
|
||||
|
||||
FullscreenTransitionWindow::FullscreenTransitionWindow(GtkWidget* aWidget)
|
||||
{
|
||||
mWindow = gtk_window_new(GTK_WINDOW_POPUP);
|
||||
GtkWindow* gtkWin = GTK_WINDOW(mWindow);
|
||||
|
||||
gtk_window_set_type_hint(gtkWin, GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
|
||||
gtk_window_set_transient_for(gtkWin, GTK_WINDOW(aWidget));
|
||||
gtk_window_set_decorated(gtkWin, false);
|
||||
|
||||
GdkScreen* screen = gtk_widget_get_screen(aWidget);
|
||||
gint width = gdk_screen_get_width(screen);
|
||||
gint height = gdk_screen_get_height(screen);
|
||||
gtk_window_set_screen(gtkWin, screen);
|
||||
gtk_window_move(gtkWin, 0, 0);
|
||||
gtk_window_resize(gtkWin, width, height);
|
||||
|
||||
GdkColor bgColor;
|
||||
bgColor.red = bgColor.green = bgColor.blue = 0;
|
||||
gtk_widget_modify_bg(mWindow, GTK_STATE_NORMAL, &bgColor);
|
||||
|
||||
gtk_window_set_opacity(gtkWin, 0.0);
|
||||
gtk_widget_show(mWindow);
|
||||
}
|
||||
|
||||
FullscreenTransitionWindow::~FullscreenTransitionWindow()
|
||||
{
|
||||
gtk_widget_destroy(mWindow);
|
||||
}
|
||||
|
||||
class FullscreenTransitionData
|
||||
{
|
||||
public:
|
||||
FullscreenTransitionData(nsIWidget::FullscreenTransitionStage aStage,
|
||||
uint16_t aDuration, nsIRunnable* aCallback,
|
||||
FullscreenTransitionWindow* aWindow)
|
||||
: mStage(aStage)
|
||||
, mStep(0)
|
||||
, mTotalSteps(aDuration / sInterval)
|
||||
, mCallback(aCallback)
|
||||
, mWindow(aWindow) { }
|
||||
|
||||
static const guint sInterval = 10; // 10ms
|
||||
static gboolean TimeoutCallback(gpointer aData);
|
||||
|
||||
private:
|
||||
nsIWidget::FullscreenTransitionStage mStage;
|
||||
uint16_t mStep, mTotalSteps;
|
||||
nsCOMPtr<nsIRunnable> mCallback;
|
||||
nsRefPtr<FullscreenTransitionWindow> mWindow;
|
||||
};
|
||||
|
||||
/* static */ gboolean
|
||||
FullscreenTransitionData::TimeoutCallback(gpointer aData)
|
||||
{
|
||||
auto data = static_cast<FullscreenTransitionData*>(aData);
|
||||
data->mStep++;
|
||||
gdouble opacity = data->mStep / gdouble(data->mTotalSteps);
|
||||
if (data->mStage == nsIWidget::eAfterFullscreenToggle) {
|
||||
opacity = 1.0 - opacity;
|
||||
}
|
||||
gtk_window_set_opacity(GTK_WINDOW(data->mWindow->mWindow), opacity);
|
||||
|
||||
if (data->mStep != data->mTotalSteps) {
|
||||
return TRUE;
|
||||
}
|
||||
NS_DispatchToMainThread(data->mCallback.forget());
|
||||
delete data;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* virtual */ bool
|
||||
nsWindow::PrepareForFullscreenTransition(nsISupports** aData)
|
||||
{
|
||||
GdkScreen* screen = gtk_widget_get_screen(mShell);
|
||||
if (!gdk_screen_is_composited(screen)) {
|
||||
return false;
|
||||
}
|
||||
*aData = do_AddRef(new FullscreenTransitionWindow(mShell)).take();
|
||||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
nsWindow::PerformFullscreenTransition(FullscreenTransitionStage aStage,
|
||||
uint16_t aDuration, nsISupports* aData,
|
||||
nsIRunnable* aCallback)
|
||||
{
|
||||
auto data = static_cast<FullscreenTransitionWindow*>(aData);
|
||||
// This will be released at the end of the last timeout callback for it.
|
||||
auto transitionData = new FullscreenTransitionData(aStage, aDuration,
|
||||
aCallback, data);
|
||||
g_timeout_add_full(G_PRIORITY_HIGH,
|
||||
FullscreenTransitionData::sInterval,
|
||||
FullscreenTransitionData::TimeoutCallback,
|
||||
transitionData, nullptr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen)
|
||||
{
|
||||
|
|
|
@ -147,6 +147,11 @@ public:
|
|||
bool aIntersectWithExisting) override;
|
||||
virtual bool HasPendingInputEvent() override;
|
||||
|
||||
virtual bool PrepareForFullscreenTransition(nsISupports** aData) override;
|
||||
virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage,
|
||||
uint16_t aDuration,
|
||||
nsISupports* aData,
|
||||
nsIRunnable* aCallback) override;
|
||||
NS_IMETHOD MakeFullScreen(bool aFullScreen,
|
||||
nsIScreen* aTargetScreen = nullptr) override;
|
||||
NS_IMETHOD HideWindowChrome(bool aShouldHide) override;
|
||||
|
|
Загрузка…
Ссылка в новой задаче