Bug 1160014 part 6 - Implement fullscreen transition for GTK. r=roc

--HG--
extra : source : ae8bf45b7efcd297ad92039b5ea6985dbfa725e9
This commit is contained in:
Xidorn Quan 2015-07-24 09:45:00 +10:00
Родитель 76b36e0a05
Коммит 7ec583cc8f
3 изменённых файлов: 120 добавлений и 0 удалений

Просмотреть файл

@ -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;