diff --git a/src/citra_qt/configuration/configure_graphics.ui b/src/citra_qt/configuration/configure_graphics.ui
index 228f2a869..b340149d5 100644
--- a/src/citra_qt/configuration/configure_graphics.ui
+++ b/src/citra_qt/configuration/configure_graphics.ui
@@ -146,17 +146,22 @@
            <widget class="QComboBox" name="layout_combobox">
             <item>
              <property name="text">
-              <string notr="true">Default</string>
+              <string>Default</string>
              </property>
             </item>
             <item>
              <property name="text">
-              <string notr="true">Single Screen</string>
+              <string>Single Screen</string>
              </property>
             </item>
             <item>
              <property name="text">
-              <string notr="true">Large Screen</string>
+              <string>Large Screen</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>Side by Side</string>
              </property>
             </item>
            </widget>
diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp
index 60b20d4e2..54fa5c7fa 100644
--- a/src/core/frontend/emu_window.cpp
+++ b/src/core/frontend/emu_window.cpp
@@ -74,6 +74,9 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height)
         case Settings::LayoutOption::LargeScreen:
             layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen);
             break;
+        case Settings::LayoutOption::SideScreen:
+            layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen);
+            break;
         case Settings::LayoutOption::Default:
         default:
             layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen);
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index d2d02f9ff..e9f778fcb 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -141,6 +141,40 @@ FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool swapped
     return res;
 }
 
+FramebufferLayout SideFrameLayout(unsigned width, unsigned height, bool swapped) {
+    ASSERT(width > 0);
+    ASSERT(height > 0);
+
+    FramebufferLayout res{width, height, true, true, {}, {}};
+    // Aspect ratio of both screens side by side
+    const float emulation_aspect_ratio = static_cast<float>(Core::kScreenTopHeight) /
+                                         (Core::kScreenTopWidth + Core::kScreenBottomWidth);
+    float window_aspect_ratio = static_cast<float>(height) / width;
+    MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height};
+    // Find largest Rectangle that can fit in the window size with the given aspect ratio
+    MathUtil::Rectangle<unsigned> screen_rect =
+        maxRectangle(screen_window_area, emulation_aspect_ratio);
+    // Find sizes of top and bottom screen
+    MathUtil::Rectangle<unsigned> top_screen = maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO);
+    MathUtil::Rectangle<unsigned> bot_screen = maxRectangle(screen_rect, BOT_SCREEN_ASPECT_RATIO);
+
+    if (window_aspect_ratio < emulation_aspect_ratio) {
+        // Apply borders to the left and right sides of the window.
+        u32 shift_horizontal = (screen_window_area.GetWidth() - screen_rect.GetWidth()) / 2;
+        top_screen = top_screen.TranslateX(shift_horizontal);
+        bot_screen = bot_screen.TranslateX(shift_horizontal);
+    } else {
+        // Window is narrower than the emulation content => apply borders to the top and bottom
+        u32 shift_vertical = (screen_window_area.GetHeight() - screen_rect.GetHeight()) / 2;
+        top_screen = top_screen.TranslateY(shift_vertical);
+        bot_screen = bot_screen.TranslateY(shift_vertical);
+    }
+    // Move the top screen to the right if we are swapped.
+    res.top_screen = swapped ? top_screen.TranslateX(bot_screen.GetWidth()) : top_screen;
+    res.bottom_screen = swapped ? bot_screen : bot_screen.TranslateX(top_screen.GetWidth());
+    return res;
+}
+
 FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) {
     ASSERT(width > 0);
     ASSERT(height > 0);
@@ -158,4 +192,4 @@ FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) {
     res.bottom_screen = bot_screen;
     return res;
 }
-}
+} // namespace Layout
diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h
index 9a7738969..4983cf103 100644
--- a/src/core/frontend/framebuffer_layout.h
+++ b/src/core/frontend/framebuffer_layout.h
@@ -53,6 +53,17 @@ FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool is_swa
  */
 FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool is_swapped);
 
+/**
+* Factory method for constructing a Frame with the Top screen and bottom
+* screen side by side
+* This is useful for devices with small screens, like the GPDWin
+* @param width Window framebuffer width in pixels
+* @param height Window framebuffer height in pixels
+* @param is_swapped if true, the bottom screen will be the left display
+* @return Newly created FramebufferLayout object with default screen regions initialized
+*/
+FramebufferLayout SideFrameLayout(unsigned width, unsigned height, bool is_swapped);
+
 /**
  * Factory method for constructing a custom FramebufferLayout
  * @param width Window framebuffer width in pixels
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index d4f0429d1..efcf1267d 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -36,4 +36,4 @@ void Apply() {
     Service::IR::ReloadInputDevices();
 }
 
-} // namespace
+} // namespace Settings
diff --git a/src/core/settings.h b/src/core/settings.h
index 7e15b119b..ca657719a 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -15,6 +15,7 @@ enum class LayoutOption {
     Default,
     SingleScreen,
     LargeScreen,
+    SideScreen,
 };
 
 namespace NativeButton {
@@ -70,7 +71,7 @@ enum Values {
 static const std::array<const char*, NumAnalogs> mapping = {{
     "circle_pad", "c_stick",
 }};
-} // namespace NumAnalog
+} // namespace NativeAnalog
 
 struct Values {
     // CheckNew3DS
@@ -137,4 +138,4 @@ struct Values {
 static constexpr int REGION_VALUE_AUTO_SELECT = -1;
 
 void Apply();
-}
+} // namespace Settings