diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/ResizeAndMovePagePubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/ResizeAndMovePagePubMsgHdlr.scala
index f0694832a6586af47a4a8b34460dfabce6611afc..dbb58eef3331c1c57f82a6b6f2a9fd2d4cc92af5 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/ResizeAndMovePagePubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/ResizeAndMovePagePubMsgHdlr.scala
@@ -3,6 +3,7 @@ package org.bigbluebutton.core.apps.presentation
 import org.bigbluebutton.common2.msgs._
 import org.bigbluebutton.common2.domain.PageVO
 import org.bigbluebutton.core.running.OutMsgRouter
+import org.bigbluebutton.core.models.Users2x
 
 trait ResizeAndMovePagePubMsgHdlr {
   this: PresentationApp2x =>
@@ -24,10 +25,12 @@ trait ResizeAndMovePagePubMsgHdlr {
       //record(event)
     }
 
-    for {
-      page <- resizeAndMovePage(msg.body.presentationId, msg.body.pageId, msg.body.xOffset, msg.body.yOffset, msg.body.widthRatio, msg.body.heightRatio)
-    } yield {
-      broadcastEvent(msg, page)
+    if (Users2x.isPresenter(msg.header.userId, liveMeeting.users2x)) {
+      for {
+        page <- resizeAndMovePage(msg.body.presentationId, msg.body.pageId, msg.body.xOffset, msg.body.yOffset, msg.body.widthRatio, msg.body.heightRatio)
+      } yield {
+        broadcastEvent(msg, page)
+      }
     }
   }
 }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/model/PagePositionBroadcaster.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/model/PagePositionBroadcaster.as
new file mode 100755
index 0000000000000000000000000000000000000000..237c567a8a70aaf0332f674483e7ea978fcc8c69
--- /dev/null
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/model/PagePositionBroadcaster.as
@@ -0,0 +1,75 @@
+package org.bigbluebutton.modules.present.model {
+	import com.asfusion.mate.events.Dispatcher;
+	
+	import flash.events.TimerEvent;
+	import flash.utils.Timer;
+	
+	import org.bigbluebutton.modules.present.events.PresenterCommands;
+
+	public class PagePositionBroadcaster {
+		
+		private var updateTimer:Timer;
+		
+		private var lastSentPosition:PagePosition;
+		
+		private var recentPosition:PagePosition;
+		
+		public function PagePositionBroadcaster() {
+			updateTimer = new Timer(50, 1);
+			updateTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimer);
+			
+			recentPosition = new PagePosition();
+			lastSentPosition = new PagePosition();
+		}
+		
+		public function broadcastPosition(x:Number, y:Number, width:Number, height:Number):void {
+			recentPosition = new PagePosition(x, y, width, height);
+			
+			if (!updateTimer.running) {
+				updateTimer.start();
+			}
+		}
+		
+		public function reset():void {
+			if (updateTimer.running) {
+				updateTimer.stop();
+			}
+			
+			recentPosition = new PagePosition();
+			lastSentPosition = new PagePosition();
+		}
+		
+		private function onTimer(e:TimerEvent):void {
+			if (!lastSentPosition.equals(recentPosition)) {
+				var globalDispatcher:Dispatcher = new Dispatcher();
+				
+				var moveEvent:PresenterCommands = new PresenterCommands(PresenterCommands.ZOOM);
+				moveEvent.xOffset = recentPosition.x;
+				moveEvent.yOffset = recentPosition.y;
+				moveEvent.slideToCanvasWidthRatio = recentPosition.width;
+				moveEvent.slideToCanvasHeightRatio = recentPosition.height;
+				globalDispatcher.dispatchEvent(moveEvent);
+				
+				lastSentPosition = recentPosition;
+			}
+		}
+	}
+}
+
+class PagePosition {
+	public var x:Number;
+	public var y:Number;
+	public var width:Number;
+	public var height:Number;
+	
+	public function PagePosition(x:Number = 0, y:Number = 0, width:Number = 0, height:Number = 0) {
+		this.x = x;
+		this.y = y;
+		this.width = width;
+		this.height = height;
+	}
+	
+	public function equals(other:PagePosition):Boolean {
+		return x == other.x && y == other.y && width == other.width && height == other.height;
+	}
+}
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml
index f3ae9a923d3fcbc59c632c6fddcd0f75a47823b6..0fd633573636842180ccda7638432940e2d2e8a4 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml
@@ -62,6 +62,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import org.bigbluebutton.modules.present.events.PageLoadedEvent;
 			import org.bigbluebutton.modules.present.events.PresenterCommands;
 			import org.bigbluebutton.modules.present.model.Page;
+			import org.bigbluebutton.modules.present.model.PagePositionBroadcaster;
 			import org.bigbluebutton.modules.present.model.Presentation;
 			import org.bigbluebutton.modules.present.model.PresentationModel;
 			import org.bigbluebutton.modules.present.ui.views.models.SlideCalcUtil;
@@ -83,6 +84,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			private var slideModel:SlideViewModel = new SlideViewModel();
 			
       private var pageCache:ArrayCollection = new ArrayCollection();
+			
+			private var pagePositionBroadcaster:PagePositionBroadcaster = new PagePositionBroadcaster();
       
 			private function onCreationComplete():void {
 				//slideLoader.width = this.width;
@@ -162,7 +165,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				prevMouseX = this.mouseX;
 				prevMouseY = this.mouseY;
 				stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
-				stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
+				stage.addEventListener(MouseEvent.MOUSE_UP, endDrag);
 				Mouse.cursor = MouseCursor.HAND;
 			}
 			
@@ -185,12 +188,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			}
 						
 			/**
-			 * Triggered when the presenter releases the mouse button.
+			 * Triggered when the presenter releases the mouse button or mouses out of the application
 			 */		
-			private function onMouseUp(e:MouseEvent):void{		
+			private function endDrag(e:MouseEvent = null):void {
 				Mouse.cursor = MouseCursor.AUTO;
 				stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
-				stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
+				stage.removeEventListener(MouseEvent.MOUSE_UP, endDrag);
 			}
 						
 			public function onParentResized(parentWidth:Number, parentHeight:Number):void {
@@ -270,12 +273,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			}
 									
 			private function notifyOthersOfZoomEvent():void {
-				var presentEvent:PresenterCommands = new PresenterCommands(PresenterCommands.ZOOM);
-				presentEvent.xOffset = slideModel.viewedRegionX;
-				presentEvent.yOffset = slideModel.viewedRegionY;
-				presentEvent.slideToCanvasWidthRatio = slideModel.viewedRegionW;
-				presentEvent.slideToCanvasHeightRatio = slideModel.viewedRegionH;
-				dispatchEvent(presentEvent);
+				pagePositionBroadcaster.broadcastPosition(slideModel.viewedRegionX, slideModel.viewedRegionY, slideModel.viewedRegionW, slideModel.viewedRegionH);
 			}
 			
 			private function presenterIsZoomingOut(delta:Number):Boolean {
@@ -336,6 +334,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
       private function becomeViewer():void {
         removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelZoomEvent);
         this.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
+        
+        pagePositionBroadcaster.reset();
+        
+        endDrag();
       }
       
 			/**