Repository: pimutils/khal

Issue:
[feature request] allow disabling mouse input
from the `man` page:

>    interactive
> invokes  the  interactive version of khal, can also be invoked by calling ikhal. While ikhal can be used entirely with the keyboard, some elements respond if clicked on with a mouse (mostly by being selected).

I don't use the mouse with any application which can be used entirely with the keyboard. For instance `htop` and `fzf` have an option (a flag) to disable mouse support.

```
fzf --no-mouse
htop --no-mouse
```

Discussion:

Patch:
diff --git a/.gitignore b/.gitignore
index 1920041..d022b15 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ env/
 venv/
 .hypothesis/
 .python-version
+.dmypy.json
diff --git a/AUTHORS.txt b/AUTHORS.txt
index a312f47..1f5297d 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -52,3 +52,4 @@ Jason Cox - me [at] jasoncarloscox [dot] com - https://jasoncarloscox.com
 Michael Tretter - michael.tretter [at] posteo [dot] net
 Raúl Medina - raulmgcontact [at] gmail (dot] com
 Matthew Rademaker - matthew.rademaker [at] gmail [dot] com
+Valentin Iovene - val [at] too [dot] gy
diff --git a/khal.conf.sample b/khal.conf.sample
index 243bb55..494a2da 100644
--- a/khal.conf.sample
+++ b/khal.conf.sample
@@ -30,3 +30,4 @@ monthdisplay = firstday
 default_calendar = home
 timedelta = 2d # the default timedelta that list uses
 highlight_event_days = True  # the default is False
+enable_mouse = True  # mouse is enabled by default in interactive mode
diff --git a/khal/cli.py b/khal/cli.py
index 8b920f5..538ff9d 100644
--- a/khal/cli.py
+++ b/khal/cli.py
@@ -93,6 +93,16 @@ def multi_calendar_option(f):
     return d(a(f))
 
 
+def mouse_option(f):
+    o = click.option(
+        '--mouse/--no-mouse',
+        is_flag=True,
+        default=None,
+        help='Disable mouse in interactive UI'
+    )
+    return o(f)
+
+
 def _select_one_calendar_callback(ctx, option, calendar):
     if isinstance(calendar, tuple):
         if len(calendar) > 1:
@@ -480,9 +490,12 @@ def _get_cli():
 
     @cli.command()
     @multi_calendar_option
+    @mouse_option
     @click.pass_context
-    def interactive(ctx, include_calendar, exclude_calendar):
+    def interactive(ctx, include_calendar, exclude_calendar, mouse):
         '''Interactive UI. Also launchable via `ikhal`.'''
+        if mouse is not None:
+            ctx.obj['conf']['default']['enable_mouse'] = mouse
         controllers.interactive(
             build_collection(
                 ctx.obj['conf'],
@@ -494,10 +507,13 @@ def _get_cli():
     @click.command()
     @global_options
     @multi_calendar_option
+    @mouse_option
     @click.pass_context
-    def interactive_cli(ctx, config, include_calendar, exclude_calendar):
+    def interactive_cli(ctx, config, include_calendar, exclude_calendar, mouse):
         '''Interactive UI. Also launchable via `khal interactive`.'''
         prepare_context(ctx, config)
+        if mouse is not None:
+            ctx.obj['conf']['default']['enable_mouse'] = mouse
         controllers.interactive(
             build_collection(
                 ctx.obj['conf'],
diff --git a/khal/settings/khal.spec b/khal/settings/khal.spec
index 789b103..fb9e50f 100644
--- a/khal/settings/khal.spec
+++ b/khal/settings/khal.spec
@@ -216,6 +216,10 @@ default_event_duration = timedelta(default='1d')
 # Define the default duration for an event ('khal new' only)
 default_dayevent_duration = timedelta(default='1h')
 
+# Whether the mouse should be enabled in interactive mode ('khal interactive' and
+# 'ikhal' only)
+enable_mouse = boolean(default=True)
+
 
 # The view section contains configuration options that effect the visual appearance
 # when using khal and ikhal.
diff --git a/khal/ui/__init__.py b/khal/ui/__init__.py
index b3f1118..1a93f78 100644
--- a/khal/ui/__init__.py
+++ b/khal/ui/__init__.py
@@ -1345,7 +1345,12 @@ def start_pane(pane, callback, program_info='', quit_keys=None):
     palette = _add_calendar_colors(
         getattr(colors, pane._conf['view']['theme']), pane.collection)
     loop = urwid.MainLoop(
-        frame, palette, unhandled_input=frame.on_key_press, pop_ups=True)
+        widget=frame,
+        palette=palette,
+        unhandled_input=frame.on_key_press,
+        pop_ups=True,
+        handle_mouse=pane._conf['default']['enable_mouse'],
+    )
     frame.loop = loop
 
     def redraw_today(loop, pane, meta=None):


Test patch:
diff --git a/tests/settings_test.py b/tests/settings_test.py
index 22dec97..586e696 100644
--- a/tests/settings_test.py
+++ b/tests/settings_test.py
@@ -55,6 +55,7 @@ class TestSettings:
                 'default_event_duration': dt.timedelta(days=1),
                 'default_dayevent_duration': dt.timedelta(hours=1),
                 'show_all_days': False,
+                'enable_mouse': True,
             }
         }
         for key in comp_config:
@@ -102,8 +103,8 @@ class TestSettings:
                 'timedelta': dt.timedelta(days=2),
                 'default_event_duration': dt.timedelta(days=1),
                 'default_dayevent_duration': dt.timedelta(hours=1),
-
-                'show_all_days': False
+                'show_all_days': False,
+                'enable_mouse': True,
             }
         }
         for key in comp_config: