diff --git a/docs/userguide b/docs/userguide
index 7064dcef..fdfb121b 100644
--- a/docs/userguide
+++ b/docs/userguide
@@ -1039,12 +1039,28 @@ popup_during_fullscreen smart
 
 === Focus wrapping
 
-When in a container with several windows or child containers, the opposite
-window will be focused when trying to move the focus over the edge of a
-container (and there are no other containers in that direction) -- the focus
-wraps. If however there is another window or container in that direction, focus
-will be set on that window or container. This is the default behavior so you
-can navigate to all your windows without having to use +focus parent+.
+By default, when in a container with several windows or child containers, the
+opposite window will be focused when trying to move the focus over the edge of
+a container (and there are no other containers in that direction) -- the focus
+wraps.
+
+If desired, you can disable this behavior using the +focus_wrapping+
+configuration directive:
+
+*Syntax*:
+---------------------
+focus_wrapping yes|no
+---------------------
+
+*Example*:
+-----------------
+focus_wrapping no
+-----------------
+
+By default, focus wrapping does not occur if there is another window or
+container in the specified direction, and focus will instead be set on that
+window or container. This is the default behavior so you can navigate to all
+your windows without having to use +focus parent+.
 
 If you want the focus to *always* wrap and you are aware of using +focus
 parent+ to switch to different containers, you can use the
diff --git a/include/config_directives.h b/include/config_directives.h
index b729e728..66defa8f 100644
--- a/include/config_directives.h
+++ b/include/config_directives.h
@@ -49,6 +49,7 @@ CFGFUN(workspace_layout, const char *layout);
 CFGFUN(workspace_back_and_forth, const char *value);
 CFGFUN(focus_follows_mouse, const char *value);
 CFGFUN(mouse_warping, const char *value);
+CFGFUN(focus_wrapping, const char *value);
 CFGFUN(force_focus_wrapping, const char *value);
 CFGFUN(force_xinerama, const char *value);
 CFGFUN(disable_randr15, const char *value);
diff --git a/include/configuration.h b/include/configuration.h
index 4f6e5ce8..33df2c2d 100644
--- a/include/configuration.h
+++ b/include/configuration.h
@@ -137,6 +137,14 @@ struct Config {
      * comes with i3. Thus, you can turn it off entirely. */
     bool disable_workspace_bar;
 
+    /** When focus wrapping is enabled (the default), attempting to
+     * move focus past the edge of the screen (in other words, in a
+     * direction in which there are no more containers to focus) will
+     * cause the focus to wrap to the opposite edge of the current
+     * container. When it is disabled, nothing happens; the current
+     * focus is preserved.  */
+    bool focus_wrapping;
+
     /** Think of the following layout: Horizontal workspace with a tabbed
      * con on the left of the screen and a terminal on the right of the
      * screen. You are in the second container in the tabbed container and
diff --git a/parser-specs/config.spec b/parser-specs/config.spec
index 665b046a..3a10bbc1 100644
--- a/parser-specs/config.spec
+++ b/parser-specs/config.spec
@@ -36,6 +36,7 @@ state INITIAL:
   'no_focus'                               -> NO_FOCUS
   'focus_follows_mouse'                    -> FOCUS_FOLLOWS_MOUSE
   'mouse_warping'                          -> MOUSE_WARPING
+  'focus_wrapping'                         -> FOCUS_WRAPPING
   'force_focus_wrapping'                   -> FORCE_FOCUS_WRAPPING
   'force_xinerama', 'force-xinerama'       -> FORCE_XINERAMA
   'disable_randr15', 'disable-randr15'     -> DISABLE_RANDR15
@@ -203,6 +204,11 @@ state MOUSE_WARPING:
   value = 'none', 'output'
       -> call cfg_mouse_warping($value)
 
+# focus_wrapping
+state FOCUS_WRAPPING:
+  value = word
+      -> call cfg_focus_wrapping($value)
+
 # force_focus_wrapping
 state FORCE_FOCUS_WRAPPING:
   value = word
diff --git a/src/config.c b/src/config.c
index 7e08b520..c8e9bd6b 100644
--- a/src/config.c
+++ b/src/config.c
@@ -227,6 +227,8 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
     if (config.workspace_urgency_timer == 0)
         config.workspace_urgency_timer = 0.5;
 
+    config.focus_wrapping = true;
+
     parse_configuration(override_configpath, true);
 
     if (reload) {
diff --git a/src/config_directives.c b/src/config_directives.c
index 376397e8..41d21dec 100644
--- a/src/config_directives.c
+++ b/src/config_directives.c
@@ -264,6 +264,10 @@ CFGFUN(disable_randr15, const char *value) {
     config.disable_randr15 = eval_boolstr(value);
 }
 
+CFGFUN(focus_wrapping, const char *value) {
+    config.focus_wrapping = eval_boolstr(value);
+}
+
 CFGFUN(force_focus_wrapping, const char *value) {
     config.force_focus_wrapping = eval_boolstr(value);
 }
diff --git a/src/tree.c b/src/tree.c
index 7f466583..97c02798 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -675,7 +675,7 @@ static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap)
  *
  */
 void tree_next(char way, orientation_t orientation) {
-    _tree_next(focused, way, orientation, true);
+    _tree_next(focused, way, orientation, config.focus_wrapping);
 }
 
 /*
diff --git a/testcases/t/201-config-parser.t b/testcases/t/201-config-parser.t
index e8080a73..3e2c4297 100644
--- a/testcases/t/201-config-parser.t
+++ b/testcases/t/201-config-parser.t
@@ -470,6 +470,7 @@ my $expected_all_tokens = "ERROR: CONFIG: Expected one of these tokens: <end>, '
         no_focus
         focus_follows_mouse
         mouse_warping
+        focus_wrapping
         force_focus_wrapping
         force_xinerama
         force-xinerama
diff --git a/testcases/t/539-disable_focus_wrapping.t b/testcases/t/539-disable_focus_wrapping.t
new file mode 100644
index 00000000..8d2e8472
--- /dev/null
+++ b/testcases/t/539-disable_focus_wrapping.t
@@ -0,0 +1,51 @@
+#!perl
+# vim:ts=4:sw=4:expandtab
+#
+# Please read the following documents before working on tests:
+# • http://build.i3wm.org/docs/testsuite.html
+#   (or docs/testsuite)
+#
+# • http://build.i3wm.org/docs/lib-i3test.html
+#   (alternatively: perldoc ./testcases/lib/i3test.pm)
+#
+# • http://build.i3wm.org/docs/ipc.html
+#   (or docs/ipc)
+#
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
+#   (unless you are already familiar with Perl)
+#
+# Tests that focus does not wrap when focus_wrapping is disabled in
+# the configuration.
+# Ticket: #2352
+# Bug still in: 4.14-72-g6411130c
+use i3test i3_config => <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+
+focus_wrapping no
+EOT
+
+sub test_orientation {
+    my ($orientation, $prev, $next) = @_;
+    my $tmp = fresh_workspace;
+
+    cmd "split $orientation";
+
+    my $win1 = open_window;
+    my $win2 = open_window;
+
+    is($x->input_focus, $win2->id, "Second window focused initially");
+    cmd "focus $prev";
+    is($x->input_focus, $win1->id, "First window focused");
+    cmd "focus $prev";
+    is($x->input_focus, $win1->id, "First window still focused");
+    cmd "focus $next";
+    is($x->input_focus, $win2->id, "Second window focused");
+    cmd "focus $next";
+    is($x->input_focus, $win2->id, "Second window still focused");
+}
+
+test_orientation('v', 'up', 'down');
+test_orientation('h', 'left', 'right');
+
+done_testing;