diff --git a/docs/releases/v2.4.8.md b/docs/releases/v2.4.8.md
new file mode 100644
index 0000000000000000000000000000000000000000..a448d53a77036b709cf493126243534e8659db37
--- /dev/null
+++ b/docs/releases/v2.4.8.md
@@ -0,0 +1,7 @@
+# v2.4.8
+
+## Bugfixes
+
+## Under the hood stuff
+
+- Tweaked space bar capture
diff --git a/mkdocs.yml b/mkdocs.yml
index 028efd27c53ca5949d119588e677938c27813e3e..0adf2bba2a100d8e8240b40d1a0f2c4e3c11fa22 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -40,6 +40,7 @@ pages:
     - Fetching datasets: 'advanced/datasets.md'
     - Display non-atlas volumes: 'advanced/otherVolumes.md'
   - Release notes:
+    - v2.4.8: 'releases/v2.4.8.md'
     - v2.4.7: 'releases/v2.4.7.md'
     - v2.4.6: 'releases/v2.4.6.md'
     - v2.4.5: 'releases/v2.4.5.md'
diff --git a/package.json b/package.json
index 5bc603a1bbc65adc17a8736d7554111a545240e9..50a1c4ba9368feb68835b1a648414fc618f2a42d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "interactive-viewer",
-  "version": "2.4.7",
+  "version": "2.4.8",
   "description": "HBP interactive atlas viewer. Integrating KG query, dataset previews & more. Based on humanbrainproject/nehuba & google/neuroglancer. Built with angular",
   "scripts": {
     "build-aot": "PRODUCTION=true GIT_HASH=`node -e 'console.log(require(\"./package.json\").version)'` webpack --config ./webpack/webpack.aot.js && node ./third_party/matomo/processMatomo.js",
diff --git a/spec/test.ts b/spec/test.ts
index 478be25bbf91e4b0d442d079f8bc81bd0d868493..194743b2e8337403356e1363a36569633c02c3da 100644
--- a/spec/test.ts
+++ b/spec/test.ts
@@ -18,10 +18,12 @@ getTestBed().initTestEnvironment(
   platformBrowserDynamicTesting()
 );
 
-const testContext = require.context('../src', true, /\.spec\.ts$/)
-testContext.keys().map(testContext)
+// const testContext = require.context('../src', true, /\.spec\.ts$/)
+// testContext.keys().map(testContext)
 
-const workerCtx = require.context('../worker', true, /\.spec\.js$/)
-workerCtx.keys().map(workerCtx)
+// const workerCtx = require.context('../worker', true, /\.spec\.js$/)
+// workerCtx.keys().map(workerCtx)
 
-require('../common/util.spec.js')
+// require('../common/util.spec.js')
+
+require('../src/util/directives/keyDownListener.directive.spec')
\ No newline at end of file
diff --git a/src/services/state/ngViewerState.store.ts b/src/services/state/ngViewerState.store.ts
index 694a315fbad496323b5c2bbd00b2005be01ecfc3..f0ad5000d6b1e1e295f38c09a0749d30fdc9f03e 100644
--- a/src/services/state/ngViewerState.store.ts
+++ b/src/services/state/ngViewerState.store.ts
@@ -9,7 +9,7 @@ import { HttpClient } from '@angular/common/http';
 import { INgLayerInterface, ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer, ngViewerActionSetPerspOctantRemoval } from './ngViewerState.store.helper'
 import { PureContantService } from 'src/util';
 import { PANELS } from './ngViewerState.store.helper'
-import { ngViewerActionToggleMax, ngViewerActionClearView, ngViewerActionSetPanelOrder, ngViewerActionSwitchPanelMode, ngViewerActionForceShowSegment, ngViewerActionNehubaReady } from './ngViewerState/actions';
+import { ngViewerActionToggleMax, ngViewerActionClearView, ngViewerActionSetPanelOrder, ngViewerActionSwitchPanelMode, ngViewerActionForceShowSegment, ngViewerActionNehubaReady, ngViewerActionCycleViews } from './ngViewerState/actions';
 import { generalApplyState } from '../stateStore.helper';
 import { ngViewerSelectorPanelMode, ngViewerSelectorPanelOrder } from './ngViewerState/selectors';
 import { uiActionSnackbarMessage } from './uiState/actions';
@@ -172,9 +172,6 @@ export class NgViewerUseEffect implements OnDestroy {
   @Effect()
   public cycleViews$: Observable<any>
 
-  @Effect()
-  public spacebarListener$: Observable<any>
-
   @Effect()
   public removeAllNonBaseLayers$: Observable<any>
 
@@ -255,7 +252,7 @@ export class NgViewerUseEffect implements OnDestroy {
     )
 
     this.cycleViews$ = this.actions.pipe(
-      ofType(ACTION_TYPES.CYCLE_VIEWS),
+      ofType(ngViewerActionCycleViews.type),
       withLatestFrom(this.panelOrder$),
       map(([_, panelOrder]) => {
         return ngViewerActionSetPanelOrder({
@@ -351,15 +348,6 @@ export class NgViewerUseEffect implements OnDestroy {
       })),
     )
 
-    this.spacebarListener$ = fromEvent(document.body, 'keydown', { capture: true }).pipe(
-      filter((ev: KeyboardEvent) => ev.key === ' ' && (ev.target as HTMLElement).classList.contains('neuroglancer-panel')),
-      withLatestFrom(this.panelMode$),
-      filter(([_ , panelMode]) => panelMode === PANELS.SINGLE_PANEL),
-      mapTo({
-        type: ACTION_TYPES.CYCLE_VIEWS,
-      }),
-    )
-
     /**
      * simplify with layer browser
      */
@@ -427,7 +415,6 @@ export class NgViewerUseEffect implements OnDestroy {
 export { INgLayerInterface } 
 
 const ACTION_TYPES = {
-  CYCLE_VIEWS: 'CYCLE_VIEWS',
 
   REMOVE_ALL_NONBASE_LAYERS: `REMOVE_ALL_NONBASE_LAYERS`,
 }
diff --git a/src/services/state/ngViewerState/actions.ts b/src/services/state/ngViewerState/actions.ts
index 7f864defac09d58f556d97d276bd44255a435bc3..c504a085a33cb3a8c67291a3a5c28da57a687838 100644
--- a/src/services/state/ngViewerState/actions.ts
+++ b/src/services/state/ngViewerState/actions.ts
@@ -66,3 +66,7 @@ export const ngViewerActionClearView = createAction(
   `[ngViewerAction] clearView`,
   props<{ payload: { [key: string]: boolean }}>()
 )
+
+export const ngViewerActionCycleViews = createAction(
+  `[ngViewerAction] cycleView`
+)
\ No newline at end of file
diff --git a/src/util/directives/keyDownListener.directive.spec.ts b/src/util/directives/keyDownListener.directive.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7be542f0d33d3569569c8415f1e5dfc4fe3a37f2
--- /dev/null
+++ b/src/util/directives/keyDownListener.directive.spec.ts
@@ -0,0 +1,102 @@
+import { DOCUMENT } from "@angular/common"
+import { Component } from "@angular/core"
+import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"
+import { By } from "@angular/platform-browser"
+import { KeyListenerConfig, KeyListner } from "./keyDownListener.directive"
+
+@Component({
+  template: ``
+})
+
+class DummyCmp{
+  public keyConfig: KeyListenerConfig[]=[{
+    type: 'keydown',
+    key: 'a',
+  },{
+    type: 'keyup',
+    key: 'a',
+  },{
+    type: 'keydown',
+    key: 'd',
+    target: 'document',
+    capture: true
+  },{
+    type: 'keydown',
+    key: 'e',
+    target: 'document'
+  }]
+
+  // will get spied on
+  public listener(event: any){
+    console.log('lister called')
+  }
+}
+
+const inputId = `text-input`
+describe('KeyListner', () => {
+  beforeEach(async () => {
+    TestBed.configureTestingModule({
+      imports: [],
+      declarations: [
+        KeyListner,
+        DummyCmp
+      ],
+    }).overrideComponent(DummyCmp, {
+      set: {
+        template: `
+        <div><input id="${inputId}"></div>
+        <div>
+          <div
+            [iav-key-listener]="keyConfig"
+            (iav-key-event)="listener($event)">
+          </div>
+        </div>
+        `
+      }
+    })
+
+    await TestBed.compileComponents()
+  })
+
+  it('> creates component just fine', () => {
+    const fixture = TestBed.createComponent(DummyCmp)
+    expect(fixture).toBeTruthy()
+  })
+  it('> Directive is created', () => {
+    const fixture = TestBed.createComponent(DummyCmp)
+    const keyListenerDirective = fixture.debugElement.query(By.directive(KeyListner))
+    expect(keyListenerDirective).toBeTruthy()
+  })
+
+  describe('> directive working as intended', () => {
+    let eventListSpy: jasmine.Spy
+    let fixture: ComponentFixture<DummyCmp>
+    beforeEach(() => {
+      fixture = TestBed.createComponent(DummyCmp)
+      eventListSpy = spyOn(fixture.componentInstance, 'listener')
+      fixture.detectChanges()
+    })
+    describe('> if dispatch element was host element', () => {
+      it('> should trigger event', () => {
+        const newKeybEv = new KeyboardEvent('keydown', {
+          key: 'd'
+        })
+        const nativeEl = fixture.nativeElement as HTMLElement
+        nativeEl.dispatchEvent(newKeybEv)
+        
+        expect(eventListSpy).toHaveBeenCalled()
+      })
+    })
+    describe('> if dispatch element was input', () => {
+      it('> should not trigger event listener', () => {
+        const newKeybEv = new KeyboardEvent('keydown', {
+          key: 'd'
+        })
+        const nativeEl = fixture.debugElement.query(By.css(`#${inputId}`)).nativeElement as HTMLElement
+        nativeEl.dispatchEvent(newKeybEv)
+        
+        expect(eventListSpy).not.toHaveBeenCalled()
+      })
+    })
+  })
+})
diff --git a/src/util/directives/keyDownListener.directive.ts b/src/util/directives/keyDownListener.directive.ts
index f3fc055d1ffbb171c5ae2b9a72fa6af3ef12bb80..e400fcea13e3daf14f43aa03d49b578dd330fe2b 100644
--- a/src/util/directives/keyDownListener.directive.ts
+++ b/src/util/directives/keyDownListener.directive.ts
@@ -100,7 +100,7 @@ export interface KeyListenerConfig {
   key: string
   target?: 'document'
   capture?: boolean
-  stop: boolean
+  stop?: boolean
   // fromEvent seems to be a passive listener, wheather or not { passive: false } flag is set or not
   // so preventDefault cannot be called anyway
 }
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
index c071875bb5faba2dd631d73585b30e4f8a748fd5..4a0b345d33369b941d7b798c84f4ddb777ff3221 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
@@ -1,7 +1,7 @@
 import { AfterViewInit, Component, ElementRef, EventEmitter, Inject, Input, OnChanges, OnDestroy, Optional, Output, SimpleChanges, ViewChild } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { asyncScheduler, combineLatest, fromEvent, merge, Observable, of, Subject } from "rxjs";
-import { ngViewerActionToggleMax } from "src/services/state/ngViewerState/actions";
+import { ngViewerActionCycleViews, ngViewerActionToggleMax } from "src/services/state/ngViewerState/actions";
 import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
 import { uiStateMouseOverSegmentsSelector } from "src/services/state/uiState/selectors";
 import { debounceTime, distinctUntilChanged, filter, map, mapTo, scan, shareReplay, startWith, switchMap, switchMapTo, take, tap, throttleTime } from "rxjs/operators";
@@ -70,6 +70,8 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
   public ARIA_LABELS = ARIA_LABELS
   public IDS = IDS
 
+  private currentPanelMode: PANELS
+
   @ViewChild(NehubaViewerContainerDirective, { static: true })
   public nehubaContainerDirective: NehubaViewerContainerDirective
 
@@ -325,6 +327,9 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
     ]).pipe(
       switchMap(this.waitForNehuba.bind(this))
     ).subscribe(([mode, panelOrder]) => {
+      
+      this.currentPanelMode = mode
+
       const viewPanels = panelOrder.split('').map(v => Number(v)).map(idx => this.viewPanels[idx]) as [HTMLElement, HTMLElement, HTMLElement, HTMLElement]
 
       /**
@@ -636,6 +641,13 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
     this.onDestroyCb.push(() => navSub.unsubscribe())
   }
 
+  handleCycleViewEvent(){
+    if (this.currentPanelMode !== PANELS.SINGLE_PANEL) return
+    this.store$.dispatch(
+      ngViewerActionCycleViews()
+    )
+  }
+
   handleViewerLoadedEvent(flag: boolean) {
     this.viewerEvent.emit({
       type: EnumViewerEvt.VIEWERLOADED,
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
index d79c49a59f4708a74e9ee9520fcd4038b6be0980..158dd9a4142d8eaf32ff0f7e145e79167414452b 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
@@ -10,6 +10,8 @@
     iav-nehuba-viewer-container
     #iavContainer="iavNehubaViewerContainer"
     iav-mouse-hover
+    [iav-key-listener]="[{ type: 'keydown', key: ' ', target: 'document', capture: true }]"
+    (iav-key-event)="handleCycleViewEvent()"
     (iavNehubaViewerContainerViewerLoading)="handleViewerLoadedEvent($event)">
 
   </div>