Compare commits
	
		
			7 Commits
		
	
	
		
			3.13.91
			...
			wip/wobbly
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					e7f82c66de | ||
| 
						 | 
					73977795a6 | ||
| 
						 | 
					3b3445146d | ||
| 
						 | 
					650dea017b | ||
| 
						 | 
					70099872ab | ||
| 
						 | 
					dc5618558f | ||
| 
						 | 
					62481f4b7c | 
@@ -90,6 +90,7 @@
 | 
			
		||||
    <file>ui/windowAttentionHandler.js</file>
 | 
			
		||||
    <file>ui/windowMenu.js</file>
 | 
			
		||||
    <file>ui/windowManager.js</file>
 | 
			
		||||
    <file>ui/wobbly.js</file>
 | 
			
		||||
    <file>ui/workspace.js</file>
 | 
			
		||||
    <file>ui/workspaceSwitcherPopup.js</file>
 | 
			
		||||
    <file>ui/workspaceThumbnail.js</file>
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -361,7 +361,7 @@ const LayoutManager = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addBackgroundMenu: function(bgManager) {
 | 
			
		||||
        BackgroundMenu.addBackgroundMenu(bgManager.background.actor, this);
 | 
			
		||||
        BackgroundMenu.addBackgroundMenu(bgManager.backgroundActor, this);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createBackgroundManager: function(monitorIndex) {
 | 
			
		||||
@@ -378,10 +378,10 @@ const LayoutManager = new Lang.Class({
 | 
			
		||||
    _showSecondaryBackgrounds: function() {
 | 
			
		||||
        for (let i = 0; i < this.monitors.length; i++) {
 | 
			
		||||
            if (i != this.primaryIndex) {
 | 
			
		||||
                let background = this._bgManagers[i].background;
 | 
			
		||||
                background.actor.show();
 | 
			
		||||
                background.actor.opacity = 0;
 | 
			
		||||
                Tweener.addTween(background.actor,
 | 
			
		||||
                let backgroundActor = this._bgManagers[i].backgroundActor;
 | 
			
		||||
                backgroundActor.show();
 | 
			
		||||
                backgroundActor.opacity = 0;
 | 
			
		||||
                Tweener.addTween(backgroundActor,
 | 
			
		||||
                                 { opacity: 255,
 | 
			
		||||
                                   time: BACKGROUND_FADE_ANIMATION_TIME,
 | 
			
		||||
                                   transition: 'easeOutQuad' });
 | 
			
		||||
@@ -404,7 +404,7 @@ const LayoutManager = new Lang.Class({
 | 
			
		||||
            this._bgManagers.push(bgManager);
 | 
			
		||||
 | 
			
		||||
            if (i != this.primaryIndex && this._startingUp)
 | 
			
		||||
                bgManager.background.actor.hide();
 | 
			
		||||
                bgManager.backgroundActor.hide();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -185,7 +185,7 @@ const Overview = new Lang.Class({
 | 
			
		||||
        for (let i = 0; i < Main.layoutManager.monitors.length; i++) {
 | 
			
		||||
            let bgManager = new Background.BackgroundManager({ container: this._backgroundGroup,
 | 
			
		||||
                                                               monitorIndex: i,
 | 
			
		||||
                                                               effects: Meta.BackgroundEffects.VIGNETTE });
 | 
			
		||||
                                                               vignette: true });
 | 
			
		||||
            this._bgManagers.push(bgManager);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
@@ -193,11 +193,9 @@ const Overview = new Lang.Class({
 | 
			
		||||
    _unshadeBackgrounds: function() {
 | 
			
		||||
        let backgrounds = this._backgroundGroup.get_children();
 | 
			
		||||
        for (let i = 0; i < backgrounds.length; i++) {
 | 
			
		||||
            let background = backgrounds[i]._delegate;
 | 
			
		||||
 | 
			
		||||
            Tweener.addTween(background,
 | 
			
		||||
            Tweener.addTween(backgrounds[i],
 | 
			
		||||
                             { brightness: 1.0,
 | 
			
		||||
                               vignetteSharpness: 0.0,
 | 
			
		||||
                               vignette_sharpness: 0.0,
 | 
			
		||||
                               time: SHADE_ANIMATION_TIME,
 | 
			
		||||
                               transition: 'easeOutQuad'
 | 
			
		||||
                             });
 | 
			
		||||
@@ -207,11 +205,9 @@ const Overview = new Lang.Class({
 | 
			
		||||
    _shadeBackgrounds: function() {
 | 
			
		||||
        let backgrounds = this._backgroundGroup.get_children();
 | 
			
		||||
        for (let i = 0; i < backgrounds.length; i++) {
 | 
			
		||||
            let background = backgrounds[i]._delegate;
 | 
			
		||||
 | 
			
		||||
            Tweener.addTween(background,
 | 
			
		||||
            Tweener.addTween(backgrounds[i],
 | 
			
		||||
                             { brightness: Lightbox.VIGNETTE_BRIGHTNESS,
 | 
			
		||||
                               vignetteSharpness: Lightbox.VIGNETTE_SHARPNESS,
 | 
			
		||||
                               vignette_sharpness: Lightbox.VIGNETTE_SHARPNESS,
 | 
			
		||||
                               time: SHADE_ANIMATION_TIME,
 | 
			
		||||
                               transition: 'easeOutQuad'
 | 
			
		||||
                             });
 | 
			
		||||
 
 | 
			
		||||
@@ -922,8 +922,10 @@ const PopupSubMenu = new Lang.Class({
 | 
			
		||||
            let [minHeight, naturalHeight] = this.actor.get_preferred_height(-1);
 | 
			
		||||
            this.actor.height = 0;
 | 
			
		||||
            this.actor._arrowRotation = this._arrow.rotation_angle_z;
 | 
			
		||||
            let angle = this.actor._arrowRotation;
 | 
			
		||||
            // animate to the first multiple of 90 greater than current angle
 | 
			
		||||
            Tweener.addTween(this.actor,
 | 
			
		||||
                             { _arrowRotation: this.actor._arrowRotation + 90,
 | 
			
		||||
                             { _arrowRotation: angle - angle % 90 + 90,
 | 
			
		||||
                               height: naturalHeight,
 | 
			
		||||
                               time: 0.25,
 | 
			
		||||
                               onUpdateScope: this,
 | 
			
		||||
@@ -955,8 +957,10 @@ const PopupSubMenu = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        if (animate) {
 | 
			
		||||
            this.actor._arrowRotation = this._arrow.rotation_angle_z;
 | 
			
		||||
            let angle = this.actor._arrowRotation;
 | 
			
		||||
            // animate to the first multiple of 90 less than current angle
 | 
			
		||||
            Tweener.addTween(this.actor,
 | 
			
		||||
                             { _arrowRotation: this.actor._arrowRotation - 90,
 | 
			
		||||
                             { _arrowRotation: (angle - 1) - (angle - 1) % 90,
 | 
			
		||||
                               height: 0,
 | 
			
		||||
                               time: 0.25,
 | 
			
		||||
                               onUpdateScope: this,
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ const Main = imports.ui.main;
 | 
			
		||||
const ModalDialog = imports.ui.modalDialog;
 | 
			
		||||
const Tweener = imports.ui.tweener;
 | 
			
		||||
const WindowMenu = imports.ui.windowMenu;
 | 
			
		||||
const Wobbly = imports.ui.wobbly;
 | 
			
		||||
 | 
			
		||||
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
 | 
			
		||||
const MAXIMIZE_WINDOW_ANIMATION_TIME = 0.15;
 | 
			
		||||
@@ -811,6 +812,8 @@ const WindowManager = new Lang.Class({
 | 
			
		||||
        gesture = new AppSwitchAction();
 | 
			
		||||
        gesture.connect('activated', Lang.bind(this, this._switchApp));
 | 
			
		||||
        global.stage.add_action(gesture);
 | 
			
		||||
 | 
			
		||||
        this._wobblyWindows = new Wobbly.WobblyWindowManager();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _lookupIndex: function (windows, metaWindow) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										130
									
								
								js/ui/wobbly.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								js/ui/wobbly.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const Meta = imports.gi.Meta;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
 | 
			
		||||
function clampAbs(v, cap) {
 | 
			
		||||
    if (v > cap)
 | 
			
		||||
        v = cap;
 | 
			
		||||
    if (v < -cap)
 | 
			
		||||
        v = -cap;
 | 
			
		||||
    return v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ActorWobbler = new Lang.Class({
 | 
			
		||||
    Name: 'ActorWobbler',
 | 
			
		||||
 | 
			
		||||
    _init: function(actor) {
 | 
			
		||||
        this._actor = actor;
 | 
			
		||||
        this._effect = new Shell.WobblyEffect();
 | 
			
		||||
        this._actor.add_effect(this._effect);
 | 
			
		||||
        this._actor._wobbler = this;
 | 
			
		||||
 | 
			
		||||
        this._currentBend = 0;
 | 
			
		||||
        this._currentHeightOffset = 0;
 | 
			
		||||
        this._running = false;
 | 
			
		||||
 | 
			
		||||
        this._allocationChangedId = this._actor.connect('allocation-changed', Lang.bind(this, this._allocationChanged));
 | 
			
		||||
 | 
			
		||||
        this._timeline = new Clutter.Timeline({ duration: 100, repeat_count: -1 });
 | 
			
		||||
        this._timeline.connect('new-frame', Lang.bind(this, this._newFrame));
 | 
			
		||||
        this._timeline.start();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    start: function() {
 | 
			
		||||
        this._running = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    stop: function() {
 | 
			
		||||
        this._running = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _destroy: function() {
 | 
			
		||||
        this._timeline.run_dispose();
 | 
			
		||||
        this._timeline = null;
 | 
			
		||||
 | 
			
		||||
        this._actor.disconnect(this._allocationChangedId);
 | 
			
		||||
        this._actor.scale_y = 1.0;
 | 
			
		||||
        this._actor.remove_effect(this._effect);
 | 
			
		||||
        this._actor._wobbler = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _newFrame: function() {
 | 
			
		||||
        this._step();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _step: function() {
 | 
			
		||||
        const DAMPEN = 0.8;
 | 
			
		||||
        this._currentBend *= DAMPEN;
 | 
			
		||||
        if (Math.abs(this._currentBend) < 1)
 | 
			
		||||
            this._currentBend = 0;
 | 
			
		||||
        this._currentHeightOffset *= DAMPEN;
 | 
			
		||||
        if (Math.abs(this._currentHeightOffset) < 1)
 | 
			
		||||
            this._currentHeightOffset = 0;
 | 
			
		||||
 | 
			
		||||
        // Cap the bend to a 100px shift.
 | 
			
		||||
        const BEND_CAP = 50;
 | 
			
		||||
        this._currentBend = clampAbs(this._currentBend, BEND_CAP);
 | 
			
		||||
        this._effect.set_bend_x(this._currentBend);
 | 
			
		||||
 | 
			
		||||
        // Cap the height change to 25px in either direction.
 | 
			
		||||
        const HEIGHT_OFFSET_CAP = 25;
 | 
			
		||||
        this._currentHeightOffset = clampAbs(this._currentHeightOffset, HEIGHT_OFFSET_CAP);
 | 
			
		||||
        let [minHeight, natHeight] = this._actor.get_preferred_height(-1);
 | 
			
		||||
        let scale = (natHeight + this._currentHeightOffset) / natHeight;
 | 
			
		||||
        this._actor.scale_y = scale;
 | 
			
		||||
 | 
			
		||||
        if (!this._running && this._currentBend == 0 && this._currentHeightOffset == 0)
 | 
			
		||||
            this._destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocationChanged: function(actor, box, flags) {
 | 
			
		||||
        if (!this._running)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this._oldX) {
 | 
			
		||||
            let deltaX = box.x1 - this._oldX;
 | 
			
		||||
            // Every 2px the user moves the window, we bend it by 1px.
 | 
			
		||||
            this._currentBend -= deltaX / 2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._oldY) {
 | 
			
		||||
            let deltaY = box.y1 - this._oldY;
 | 
			
		||||
            // Every 2px the user moves the window, we scale it by 1px.
 | 
			
		||||
            this._currentHeightOffset -= deltaY / 2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._oldX = box.x1;
 | 
			
		||||
        this._oldY = box.y1;
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const WobblyWindowManager = new Lang.Class({
 | 
			
		||||
    Name: 'WobblyWindowManager',
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        global.display.connect('grab-op-begin', Lang.bind(this, this._grabOpBegin));
 | 
			
		||||
        global.display.connect('grab-op-end', Lang.bind(this, this._grabOpEnd));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _grabOpBegin: function(display, screen, window, op) {
 | 
			
		||||
        if (op != Meta.GrabOp.MOVING)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let actor = window.get_compositor_private();
 | 
			
		||||
        if (!actor._wobbler)
 | 
			
		||||
            new ActorWobbler(actor);
 | 
			
		||||
        actor._wobbler.start();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _grabOpEnd: function(display, screen, window, op) {
 | 
			
		||||
        if (!window)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let actor = window.get_compositor_private();
 | 
			
		||||
        if (actor._wobbler)
 | 
			
		||||
            actor._wobbler.stop();
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
@@ -306,7 +306,7 @@ const WorkspaceThumbnail = new Lang.Class({
 | 
			
		||||
    _createBackground: function() {
 | 
			
		||||
        this._bgManager = new Background.BackgroundManager({ monitorIndex: Main.layoutManager.primaryIndex,
 | 
			
		||||
                                                             container: this._contents,
 | 
			
		||||
                                                             effects: Meta.BackgroundEffects.NONE });
 | 
			
		||||
                                                             vignette: false });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setPorthole: function(x, y, width, height) {
 | 
			
		||||
@@ -332,7 +332,7 @@ const WorkspaceThumbnail = new Lang.Class({
 | 
			
		||||
            let clone = this._windows[i];
 | 
			
		||||
            let metaWindow = clone.metaWindow;
 | 
			
		||||
            if (i == 0) {
 | 
			
		||||
                clone.setStackAbove(this._bgManager.background.actor);
 | 
			
		||||
                clone.setStackAbove(this._bgManager.backgroundActor);
 | 
			
		||||
            } else {
 | 
			
		||||
                let previousClone = this._windows[i - 1];
 | 
			
		||||
                clone.setStackAbove(previousClone.actor);
 | 
			
		||||
@@ -531,7 +531,7 @@ const WorkspaceThumbnail = new Lang.Class({
 | 
			
		||||
        this._contents.add_actor(clone.actor);
 | 
			
		||||
 | 
			
		||||
        if (this._windows.length == 0)
 | 
			
		||||
            clone.setStackAbove(this._bgManager.background.actor);
 | 
			
		||||
            clone.setStackAbove(this._bgManager.backgroundActor);
 | 
			
		||||
        else
 | 
			
		||||
            clone.setStackAbove(this._windows[this._windows.length - 1].actor);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -102,6 +102,7 @@ shell_public_headers_h =		\
 | 
			
		||||
	shell-util.h			\
 | 
			
		||||
	shell-window-tracker.h		\
 | 
			
		||||
	shell-wm.h			\
 | 
			
		||||
	shell-wobbly-effect.h		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if HAVE_NETWORKMANAGER
 | 
			
		||||
@@ -167,6 +168,7 @@ libgnome_shell_sources =		\
 | 
			
		||||
	shell-util.c			\
 | 
			
		||||
	shell-window-tracker.c		\
 | 
			
		||||
	shell-wm.c			\
 | 
			
		||||
	shell-wobbly-effect.c		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
libgnome_shell_built_sources =		\
 | 
			
		||||
 
 | 
			
		||||
@@ -260,6 +260,8 @@ shell_perf_log_init (void)
 | 
			
		||||
static void
 | 
			
		||||
shell_a11y_init (void)
 | 
			
		||||
{
 | 
			
		||||
  cally_accessibility_init ();
 | 
			
		||||
 | 
			
		||||
  if (clutter_get_accessibility_enabled () == FALSE)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Accessibility: clutter has no accessibility enabled"
 | 
			
		||||
@@ -422,10 +424,7 @@ main (int argc, char **argv)
 | 
			
		||||
  meta_set_wm_name (WM_NAME);
 | 
			
		||||
  meta_set_gnome_wm_keybindings (GNOME_WM_KEYBINDINGS);
 | 
			
		||||
 | 
			
		||||
  /* Prevent meta_init() from causing gtk to load gail and at-bridge */
 | 
			
		||||
  g_setenv ("NO_AT_BRIDGE", "1", TRUE);
 | 
			
		||||
  meta_init ();
 | 
			
		||||
  g_unsetenv ("NO_AT_BRIDGE");
 | 
			
		||||
 | 
			
		||||
  /* FIXME: Add gjs API to set this stuff and don't depend on the
 | 
			
		||||
   * environment.  These propagate to child processes.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										216
									
								
								src/shell-wobbly-effect.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								src/shell-wobbly-effect.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,216 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014 Endless Mobile
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "shell-wobbly-effect.h"
 | 
			
		||||
 | 
			
		||||
struct _ShellWobblyEffectPrivate
 | 
			
		||||
{
 | 
			
		||||
  int bend_x;
 | 
			
		||||
 | 
			
		||||
  int tex_width, tex_height;
 | 
			
		||||
  CoglPipeline *pipeline;
 | 
			
		||||
 | 
			
		||||
  int tex_width_uniform;
 | 
			
		||||
  int bend_x_uniform;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _ShellWobblyEffectPrivate ShellWobblyEffectPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (ShellWobblyEffect, shell_wobbly_effect, CLUTTER_TYPE_OFFSCREEN_EFFECT);
 | 
			
		||||
 | 
			
		||||
static const gchar *wobbly_decls =
 | 
			
		||||
  "uniform int tex_width;\n"
 | 
			
		||||
  "uniform int bend_x;\n";
 | 
			
		||||
static const gchar *wobbly_pre =
 | 
			
		||||
  "float bend_x_coord = (float(bend_x) / tex_width);\n"
 | 
			
		||||
  "float interp = (1 - cos(cogl_tex_coord.y * 3.1415926)) / 2;\n"
 | 
			
		||||
  "cogl_tex_coord.x -= (interp * bend_x_coord);\n";
 | 
			
		||||
 | 
			
		||||
/* XXX - clutter_effect_get_paint_volume is fucking terrible
 | 
			
		||||
 * and I want to kill myself */
 | 
			
		||||
static gboolean
 | 
			
		||||
shell_wobbly_effect_get_paint_volume (ClutterEffect      *effect,
 | 
			
		||||
                                      ClutterPaintVolume *volume)
 | 
			
		||||
{
 | 
			
		||||
  ShellWobblyEffect *self = SHELL_WOBBLY_EFFECT (effect);
 | 
			
		||||
  ShellWobblyEffectPrivate *priv = shell_wobbly_effect_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  float cur_width;
 | 
			
		||||
  cur_width = clutter_paint_volume_get_width (volume);
 | 
			
		||||
  cur_width += ABS (priv->bend_x);
 | 
			
		||||
  clutter_paint_volume_set_width (volume, cur_width);
 | 
			
		||||
 | 
			
		||||
  /* Also modify the origin if it bends to the left. */
 | 
			
		||||
  if (priv->bend_x < 0)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterVertex origin;
 | 
			
		||||
      clutter_paint_volume_get_origin (volume, &origin);
 | 
			
		||||
      origin.x += priv->bend_x;
 | 
			
		||||
      clutter_paint_volume_set_origin (volume, &origin);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
shell_wobbly_effect_pre_paint (ClutterEffect *effect)
 | 
			
		||||
{
 | 
			
		||||
  ShellWobblyEffect *self = SHELL_WOBBLY_EFFECT (effect);
 | 
			
		||||
  ShellWobblyEffectPrivate *priv = shell_wobbly_effect_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  /* If we're not doing any bending, we're not needed. */
 | 
			
		||||
  if (priv->bend_x == 0)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
 | 
			
		||||
    {
 | 
			
		||||
      /* if we don't have support for GLSL shaders then we
 | 
			
		||||
       * forcibly disable the ActorMeta
 | 
			
		||||
       */
 | 
			
		||||
      g_warning ("Unable to use the ShellWobblyEffect: the "
 | 
			
		||||
                 "graphics hardware or the current GL driver does not "
 | 
			
		||||
                 "implement support for the GLSL shading language. The "
 | 
			
		||||
                 "effect will be disabled.");
 | 
			
		||||
      clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!CLUTTER_EFFECT_CLASS (shell_wobbly_effect_parent_class)->pre_paint (effect))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (effect);
 | 
			
		||||
  CoglObject *texture;
 | 
			
		||||
 | 
			
		||||
  texture = clutter_offscreen_effect_get_texture (offscreen_effect);
 | 
			
		||||
  cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
 | 
			
		||||
 | 
			
		||||
  priv->tex_width = cogl_texture_get_width (texture);
 | 
			
		||||
  priv->tex_height = cogl_texture_get_height (texture);
 | 
			
		||||
 | 
			
		||||
  cogl_pipeline_set_uniform_1i (priv->pipeline, priv->tex_width_uniform, priv->tex_width);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_wobbly_effect_paint_target (ClutterOffscreenEffect *effect)
 | 
			
		||||
{
 | 
			
		||||
  ShellWobblyEffect *self = SHELL_WOBBLY_EFFECT (effect);
 | 
			
		||||
  ShellWobblyEffectPrivate *priv = shell_wobbly_effect_get_instance_private (self);
 | 
			
		||||
  CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
  guint8 paint_opacity;
 | 
			
		||||
 | 
			
		||||
  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
 | 
			
		||||
  paint_opacity = clutter_actor_get_paint_opacity (actor);
 | 
			
		||||
 | 
			
		||||
  cogl_pipeline_set_color4ub (priv->pipeline,
 | 
			
		||||
                              paint_opacity,
 | 
			
		||||
                              paint_opacity,
 | 
			
		||||
                              paint_opacity,
 | 
			
		||||
                              paint_opacity);
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_draw_rectangle (fb, priv->pipeline,
 | 
			
		||||
                                   0, 0, priv->tex_width, priv->tex_height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_wobbly_effect_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  ShellWobblyEffect *self = SHELL_WOBBLY_EFFECT (object);
 | 
			
		||||
  ShellWobblyEffectPrivate *priv = shell_wobbly_effect_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->pipeline, cogl_object_unref);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (shell_wobbly_effect_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_wobbly_effect_class_init (ShellWobblyEffectClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
 | 
			
		||||
  ClutterOffscreenEffectClass *offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  offscreen_class->paint_target = shell_wobbly_effect_paint_target;
 | 
			
		||||
  effect_class->pre_paint = shell_wobbly_effect_pre_paint;
 | 
			
		||||
  effect_class->get_paint_volume = shell_wobbly_effect_get_paint_volume;
 | 
			
		||||
  object_class->dispose = shell_wobbly_effect_dispose;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_uniforms (ShellWobblyEffect *self)
 | 
			
		||||
{
 | 
			
		||||
  ShellWobblyEffectPrivate *priv = shell_wobbly_effect_get_instance_private (self);
 | 
			
		||||
  cogl_pipeline_set_uniform_1i (priv->pipeline, priv->bend_x_uniform, priv->bend_x);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_wobbly_effect_init (ShellWobblyEffect *self)
 | 
			
		||||
{
 | 
			
		||||
  static CoglPipeline *pipeline_template;
 | 
			
		||||
 | 
			
		||||
  ShellWobblyEffectPrivate *priv = shell_wobbly_effect_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  if (G_UNLIKELY (pipeline_template == NULL))
 | 
			
		||||
    {
 | 
			
		||||
      CoglSnippet *snippet;
 | 
			
		||||
      CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
 | 
			
		||||
      pipeline_template = cogl_pipeline_new (ctx);
 | 
			
		||||
 | 
			
		||||
      snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, wobbly_decls, NULL);
 | 
			
		||||
      cogl_snippet_set_pre (snippet, wobbly_pre);
 | 
			
		||||
      cogl_pipeline_add_layer_snippet (pipeline_template, 0, snippet);
 | 
			
		||||
      cogl_object_unref (snippet);
 | 
			
		||||
 | 
			
		||||
      cogl_pipeline_set_layer_null_texture (pipeline_template,
 | 
			
		||||
                                            0, /* layer number */
 | 
			
		||||
                                            COGL_TEXTURE_TYPE_2D);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->pipeline = cogl_pipeline_copy (pipeline_template);
 | 
			
		||||
  priv->tex_width_uniform = cogl_pipeline_get_uniform_location (priv->pipeline, "tex_width");
 | 
			
		||||
  priv->bend_x_uniform = cogl_pipeline_get_uniform_location (priv->pipeline, "bend_x");
 | 
			
		||||
 | 
			
		||||
  update_uniforms (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
shell_wobbly_effect_set_bend_x (ShellWobblyEffect *self,
 | 
			
		||||
                                int                bend_x)
 | 
			
		||||
{
 | 
			
		||||
  ShellWobblyEffectPrivate *priv = shell_wobbly_effect_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  if (priv->bend_x == bend_x)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv->bend_x = bend_x;
 | 
			
		||||
  update_uniforms (self);
 | 
			
		||||
  clutter_effect_queue_repaint (CLUTTER_EFFECT (self));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								src/shell-wobbly-effect.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/shell-wobbly-effect.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014 Endless Mobile
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#ifndef __SHELL_WOBBLY_EFFECT_H__
 | 
			
		||||
#define __SHELL_WOBBLY_EFFECT_H__
 | 
			
		||||
 | 
			
		||||
#define SHELL_TYPE_WOBBLY_EFFECT             (shell_wobbly_effect_get_type ())
 | 
			
		||||
#define SHELL_WOBBLY_EFFECT(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_WOBBLY_EFFECT, ShellWobblyEffect))
 | 
			
		||||
#define SHELL_WOBBLY_EFFECT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  SHELL_TYPE_WOBBLY_EFFECT, ShellWobblyEffectClass))
 | 
			
		||||
#define SHELL_IS_WOBBLY_EFFECT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_WOBBLY_EFFECT))
 | 
			
		||||
#define SHELL_IS_WOBBLY_EFFECT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  SHELL_TYPE_WOBBLY_EFFECT))
 | 
			
		||||
#define SHELL_WOBBLY_EFFECT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  SHELL_TYPE_WOBBLY_EFFECT, ShellWobblyEffectClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _ShellWobblyEffect        ShellWobblyEffect;
 | 
			
		||||
typedef struct _ShellWobblyEffectClass   ShellWobblyEffectClass;
 | 
			
		||||
 | 
			
		||||
struct _ShellWobblyEffect
 | 
			
		||||
{
 | 
			
		||||
  ClutterOffscreenEffect parent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _ShellWobblyEffectClass
 | 
			
		||||
{
 | 
			
		||||
  ClutterOffscreenEffectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType shell_wobbly_effect_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void shell_wobbly_effect_set_bend_x (ShellWobblyEffect *self,
 | 
			
		||||
                                     int                bend_x);
 | 
			
		||||
 | 
			
		||||
#endif /* __SHELL_WOBBLY_EFFECT_H__ */
 | 
			
		||||
		Reference in New Issue
	
	Block a user