diff --git a/toonz/sources/toonz/keyframemover.cpp b/toonz/sources/toonz/keyframemover.cpp
index 12913ec..37b66a0 100644
--- a/toonz/sources/toonz/keyframemover.cpp
+++ b/toonz/sources/toonz/keyframemover.cpp
@@ -99,6 +99,8 @@ void KeyframeMover::start(TKeyframeSelection *selection, int qualifiers) {
 bool KeyframeMover::moveKeyframes(
     int dr, std::set<TKeyframeSelection::Position> &newPositions,
     TKeyframeSelection *selection) {
+  // return if there is no movement
+  if (dr == 0) return false;
   TXsheet *xsh = getXsheet();
   std::set<TKeyframeSelection::Position> positions;
   if (selection)
@@ -115,23 +117,52 @@ bool KeyframeMover::moveKeyframes(
       TStageObjectId objId =
           c >= 0 ? TStageObjectId::ColumnId(c) : TStageObjectId::CameraId(0);
       TStageObject *stObj = xsh->getStageObject(objId);
-      if (r + dr < 0) dr  = -r;
-      if (stObj->isKeyframe(r + dr)) return false;
+      if (r + dr < 0) {
+        dr = -r;
+        // dragging backward stops when the selection reaches the first frame
+        if (dr == 0) return false;
+      }
+      if (stObj->isKeyframe(r + dr)) {
+        if (m_qualifiers & eCopyKeyframes) return false;
+        // occupying key may be dragged one which is to be moved out
+        else if (positions.count(TKeyframeSelection::Position(r + dr, c)) == 0)
+          return false;
+      }
     }
 
     bool firstTime = false;
-    for (posIt = positions.begin(); posIt != positions.end(); ++posIt) {
-      int c = posIt->second;
-      int r = posIt->first;
-      TStageObjectId objId =
-          c >= 0 ? TStageObjectId::ColumnId(c) : TStageObjectId::CameraId(0);
-      TStageObject *stObj = xsh->getStageObject(objId);
-      if (m_qualifiers & eCopyKeyframes) {
-        firstTime = true;
-        stObj->setKeyframeWithoutUndo(r + dr, stObj->getKeyframe(r));
-      } else
-        stObj->moveKeyframe(r + dr, r);
-      newPositions.insert(TKeyframeSelection::Position(r + dr, c));
+
+    // move keys from the end of the selection on dragging forward
+    if (dr > 0) {
+      for (std::set<TKeyframeSelection::Position>::reverse_iterator revIt =
+               positions.rbegin();
+           revIt != positions.rend(); ++revIt) {
+        int c = revIt->second;
+        int r = revIt->first;
+        TStageObjectId objId =
+            c >= 0 ? TStageObjectId::ColumnId(c) : TStageObjectId::CameraId(0);
+        TStageObject *stObj = xsh->getStageObject(objId);
+        if (m_qualifiers & eCopyKeyframes) {
+          firstTime = true;
+          stObj->setKeyframeWithoutUndo(r + dr, stObj->getKeyframe(r));
+        } else
+          stObj->moveKeyframe(r + dr, r);
+        newPositions.insert(TKeyframeSelection::Position(r + dr, c));
+      }
+    } else {  // ... and vice versa
+      for (posIt = positions.begin(); posIt != positions.end(); ++posIt) {
+        int c = posIt->second;
+        int r = posIt->first;
+        TStageObjectId objId =
+            c >= 0 ? TStageObjectId::ColumnId(c) : TStageObjectId::CameraId(0);
+        TStageObject *stObj = xsh->getStageObject(objId);
+        if (m_qualifiers & eCopyKeyframes) {
+          firstTime = true;
+          stObj->setKeyframeWithoutUndo(r + dr, stObj->getKeyframe(r));
+        } else
+          stObj->moveKeyframe(r + dr, r);
+        newPositions.insert(TKeyframeSelection::Position(r + dr, c));
+      }
     }
     if (firstTime) {
       m_qualifiers = 0;