hlassiege/darylpublic Fork
⑂ 46136b1
Commits
⬇ Clone ▾
git clone https://git.rickub.com/hlassiege/daryl.git
git clone ssh://git@rickub.com/hlassiege/daryl.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

fix(web): keep Chrome's menu from grabbing focus after Alt+wheel zoom

hlassiege committed 2026-10-13T13:48:04+02:00 Browse files
46136b1 parent: 50c9d0c
modified web/src/lib/composables.ts +16 -0
@@ -25,3 +25,19 @@ export function usePolling(tick: () => Promise<number>) {
2525 onMounted(loop);
2626 onUnmounted(() => { stopped = true; clearTimeout(timer); });
2727 }
28+
29+/**
30+ * Sous Windows, relâcher Alt donne le focus au menu de Chrome (et Espace l'ouvre ensuite). Après un
31+ * Alt+molette, on annule ce relâchement : appeler la fonction renvoyée à chaque molette avec Alt.
32+ */
33+export function useAltWheel(): () => void {
34+ let used = false;
35+ const onKeyUp = (e: KeyboardEvent) => {
36+ if (e.key !== "Alt") return;
37+ if (used) e.preventDefault();
38+ used = false;
39+ };
40+ onMounted(() => window.addEventListener("keyup", onKeyUp));
41+ onUnmounted(() => window.removeEventListener("keyup", onKeyUp));
42+ return () => { used = true; };
43+}
@@ -25,3 +25,19 @@ export function usePolling(tick: () => Promise<number>) {
25 onMounted(loop);25 onMounted(loop);
26 onUnmounted(() => { stopped = true; clearTimeout(timer); });26 onUnmounted(() => { stopped = true; clearTimeout(timer); });
27 }27 }
28+
29+/**
30+ * Sous Windows, relâcher Alt donne le focus au menu de Chrome (et Espace l'ouvre ensuite). Après un
31+ * Alt+molette, on annule ce relâchement : appeler la fonction renvoyée à chaque molette avec Alt.
32+ */
33+export function useAltWheel(): () => void {
34+ let used = false;
35+ const onKeyUp = (e: KeyboardEvent) => {
36+ if (e.key !== "Alt") return;
37+ if (used) e.preventDefault();
38+ used = false;
39+ };
40+ onMounted(() => window.addEventListener("keyup", onKeyUp));
41+ onUnmounted(() => window.removeEventListener("keyup", onKeyUp));
42+ return () => { used = true; };
43+}
modified web/src/project/steps/derush/Timeline.vue +3 -0
@@ -11,6 +11,7 @@
1111 */
1212 import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue";
1313 import { useI18n } from "vue-i18n";
14+import { useAltWheel } from "../../../lib/composables";
1415 import { mmss } from "../../../lib/format";
1516 import type { DerushClip, DerushSeg, TimelineClip } from "../../types";
1617 import { clipLen, offsets, type Selection } from "./clips";
@@ -71,9 +72,11 @@ function fit() {
7172 }
7273 defineExpose({ zoomBy, fit });
7374
75+const altWheel = useAltWheel();
7476 function onWheel(e: WheelEvent) {
7577 // la molette seule fait défiler la page
7678 if (e.altKey) {
79+ altWheel();
7780 e.preventDefault();
7881 zoomBy(Math.pow(1.0015, -e.deltaY));
7982 } else if ((e.ctrlKey || e.metaKey) && Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
@@ -11,6 +11,7 @@
11 */11 */
12 import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue";12 import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue";
13 import { useI18n } from "vue-i18n";13 import { useI18n } from "vue-i18n";
14+import { useAltWheel } from "../../../lib/composables";
14 import { mmss } from "../../../lib/format";15 import { mmss } from "../../../lib/format";
15 import type { DerushClip, DerushSeg, TimelineClip } from "../../types";16 import type { DerushClip, DerushSeg, TimelineClip } from "../../types";
16 import { clipLen, offsets, type Selection } from "./clips";17 import { clipLen, offsets, type Selection } from "./clips";
@@ -71,9 +72,11 @@ function fit() {
71 }72 }
72 defineExpose({ zoomBy, fit });73 defineExpose({ zoomBy, fit });
73 74
75+const altWheel = useAltWheel();
74 function onWheel(e: WheelEvent) {76 function onWheel(e: WheelEvent) {
75 // la molette seule fait défiler la page77 // la molette seule fait défiler la page
76 if (e.altKey) {78 if (e.altKey) {
79+ altWheel();
77 e.preventDefault();80 e.preventDefault();
78 zoomBy(Math.pow(1.0015, -e.deltaY));81 zoomBy(Math.pow(1.0015, -e.deltaY));
79 } else if ((e.ctrlKey || e.metaKey) && Math.abs(e.deltaY) > Math.abs(e.deltaX)) {82 } else if ((e.ctrlKey || e.metaKey) && Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
modified web/src/project/steps/montage/Timeline.vue +3 -0
@@ -12,6 +12,7 @@
1212 */
1313 import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue";
1414 import { useI18n } from "vue-i18n";
15+import { useAltWheel } from "../../../lib/composables";
1516 import { fxName } from "../../../lib/transitions";
1617 import { MEDIA_DRAG, trimAroll } from "./ops";
1718 import {
@@ -106,9 +107,11 @@ function fit() {
106107 }
107108 defineExpose({ zoomBy, fit });
108109
110+const altWheel = useAltWheel();
109111 function onWheel(e: WheelEvent) {
110112 // la molette seule fait défiler la page (pour atteindre les pistes du bas)
111113 if (e.altKey) {
114+ altWheel();
112115 e.preventDefault();
113116 zoomBy(Math.pow(1.0015, -e.deltaY));
114117 } else if ((e.ctrlKey || e.metaKey) && Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
@@ -12,6 +12,7 @@
12 */12 */
13 import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue";13 import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue";
14 import { useI18n } from "vue-i18n";14 import { useI18n } from "vue-i18n";
15+import { useAltWheel } from "../../../lib/composables";
15 import { fxName } from "../../../lib/transitions";16 import { fxName } from "../../../lib/transitions";
16 import { MEDIA_DRAG, trimAroll } from "./ops";17 import { MEDIA_DRAG, trimAroll } from "./ops";
17 import {18 import {
@@ -106,9 +107,11 @@ function fit() {
106 }107 }
107 defineExpose({ zoomBy, fit });108 defineExpose({ zoomBy, fit });
108 109
110+const altWheel = useAltWheel();
109 function onWheel(e: WheelEvent) {111 function onWheel(e: WheelEvent) {
110 // la molette seule fait défiler la page (pour atteindre les pistes du bas)112 // la molette seule fait défiler la page (pour atteindre les pistes du bas)
111 if (e.altKey) {113 if (e.altKey) {
114+ altWheel();
112 e.preventDefault();115 e.preventDefault();
113 zoomBy(Math.pow(1.0015, -e.deltaY));116 zoomBy(Math.pow(1.0015, -e.deltaY));
114 } else if ((e.ctrlKey || e.metaKey) && Math.abs(e.deltaY) > Math.abs(e.deltaX)) {117 } else if ((e.ctrlKey || e.metaKey) && Math.abs(e.deltaY) > Math.abs(e.deltaX)) {