fix(core): add option to disable middle click paste behavior on linux (#11496)

fix BS-3028
This commit is contained in:
pengx17
2025-04-07 07:01:37 +00:00
parent 6e10fe6205
commit 952f1878a6
6 changed files with 69 additions and 13 deletions

View File

@@ -25,14 +25,13 @@ import type { DefaultOpenProperty } from '../../components/doc-properties';
import { BlocksuiteDocEditor, BlocksuiteEdgelessEditor } from './lit-adaper';
import * as styles from './styles.css';
interface BlocksuiteEditorContainerProps {
interface BlocksuiteEditorContainerProps
extends React.HTMLAttributes<HTMLDivElement> {
page: Store;
mode: DocMode;
shared?: boolean;
readonly?: boolean;
className?: string;
defaultOpenProperty?: DefaultOpenProperty;
style?: React.CSSProperties;
}
export interface AffineEditorContainer extends HTMLElement {
@@ -51,7 +50,7 @@ export const BlocksuiteEditorContainer = forwardRef<
AffineEditorContainer,
BlocksuiteEditorContainerProps
>(function AffineEditorContainer(
{ page, mode, className, style, shared, readonly, defaultOpenProperty },
{ page, mode, shared, readonly, defaultOpenProperty, ...props },
ref
) {
const rootRef = useRef<HTMLDivElement>(null);
@@ -159,15 +158,16 @@ export const BlocksuiteEditorContainer = forwardRef<
return (
<div
{...props}
data-testid={`editor-${page.id}`}
dir={enableEditorRTL ? 'rtl' : 'ltr'}
className={clsx(
`editor-wrapper ${mode}-mode`,
styles.docEditorRoot,
className
props.className
)}
data-affine-editor-container
style={style}
style={props.style}
ref={rootRef}
>
{mode === 'page' ? (

View File

@@ -16,8 +16,8 @@ import type { Store } from '@blocksuite/affine/store';
import { Slot } from '@radix-ui/react-slot';
import { useLiveData, useService } from '@toeverything/infra';
import { cssVar } from '@toeverything/theme';
import type { CSSProperties } from 'react';
import { useEffect, useMemo, useState } from 'react';
import type { CSSProperties, HTMLAttributes } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import type { DefaultOpenProperty } from '../../components/doc-properties';
import {
@@ -26,7 +26,7 @@ import {
} from './blocksuite-editor-container';
import { NoPageRootError } from './no-page-error';
export type EditorProps = {
export interface EditorProps extends HTMLAttributes<HTMLDivElement> {
page: Store;
mode: DocMode;
shared?: boolean;
@@ -34,9 +34,7 @@ export type EditorProps = {
defaultOpenProperty?: DefaultOpenProperty;
// on Editor ready
onEditorReady?: (editor: AffineEditorContainer) => (() => void) | void;
style?: CSSProperties;
className?: string;
};
}
const BlockSuiteEditorImpl = ({
mode,
@@ -47,6 +45,7 @@ const BlockSuiteEditorImpl = ({
style,
onEditorReady,
defaultOpenProperty,
...props
}: EditorProps) => {
useEffect(() => {
const disposable = page.slots.blockUpdated.subscribe(() => {
@@ -111,6 +110,7 @@ const BlockSuiteEditorImpl = ({
return (
<BlocksuiteEditorContainer
{...props}
mode={mode}
page={page}
shared={shared}
@@ -133,6 +133,7 @@ export const BlockSuiteEditor = (props: EditorProps) => {
fontFamily: s.fontFamily,
customFontFamily: s.customFontFamily,
fullWidthLayout: s.fullWidthLayout,
disableMiddleClickPaste: s.disableMiddleClickPaste,
}))
);
const fontFamily = useMemo(() => {
@@ -169,12 +170,24 @@ export const BlockSuiteEditor = (props: EditorProps) => {
};
}, [props.page]);
const handleMouseDown = useCallback(
(e: React.MouseEvent<HTMLDivElement>) => {
if (settings.disableMiddleClickPaste && e.button === 1) {
e.preventDefault();
}
},
[settings.disableMiddleClickPaste]
);
if (error) {
throw error;
}
return (
<Slot style={{ '--affine-font-family': fontFamily } as CSSProperties}>
<Slot
style={{ '--affine-font-family': fontFamily } as CSSProperties}
onMouseDown={handleMouseDown}
>
{isLoading ? (
<EditorLoading />
) : (

View File

@@ -487,6 +487,36 @@ const SpellCheckSettings = () => {
);
};
const MiddleClickPasteSettings = () => {
const t = useI18n();
const editorSettingService = useService(EditorSettingService);
const settings = useLiveData(editorSettingService.editorSetting.settings$);
const onToggleMiddleClickPaste = useCallback(
(checked: boolean) => {
editorSettingService.editorSetting.set(
'disableMiddleClickPaste',
checked
);
},
[editorSettingService.editorSetting]
);
return (
<SettingRow
name={t[
'com.affine.settings.editorSettings.general.middle-click-paste.title'
]()}
desc={t[
'com.affine.settings.editorSettings.general.middle-click-paste.description'
]()}
>
<Switch
checked={settings.disableMiddleClickPaste}
onChange={onToggleMiddleClickPaste}
/>
</SettingRow>
);
};
export const General = () => {
const t = useI18n();
@@ -497,6 +527,7 @@ export const General = () => {
<CustomFontFamilySettings />
<NewDocDefaultModeSettings />
{BUILD_CONFIG.isElectron && <SpellCheckSettings />}
{environment.isLinux && <MiddleClickPasteSettings />}
{/* // TODO(@akumatus): implement these settings
<DeFaultCodeBlockSettings />
*/}

View File

@@ -34,6 +34,8 @@ const AffineEditorSettingSchema = z.object({
'open-in-center-peek',
])
.default('open-in-active-view'),
// linux only:
disableMiddleClickPaste: z.boolean().default(false),
});
export const EditorSettingSchema = BSEditorSettingSchema.merge(

View File

@@ -5167,6 +5167,14 @@ export function useAFFiNEI18N(): {
* `Page`
*/
["com.affine.settings.editorSettings.page"](): string;
/**
* `Middle click paste`
*/
["com.affine.settings.editorSettings.general.middle-click-paste.title"](): string;
/**
* `Disable default middle click paste behavior on Linux.`
*/
["com.affine.settings.editorSettings.general.middle-click-paste.description"](): string;
/**
* `Display bi-directional links on the doc.`
*/

View File

@@ -1287,6 +1287,8 @@
"com.affine.settings.editorSettings.general.spell-check.title": "Spell check",
"com.affine.settings.editorSettings.general.spell-check.restart-hint": "Settings changed; please restart the app. <1>Restart</1>",
"com.affine.settings.editorSettings.page": "Page",
"com.affine.settings.editorSettings.general.middle-click-paste.title": "Middle click paste",
"com.affine.settings.editorSettings.general.middle-click-paste.description": "Disable default middle click paste behavior on Linux.",
"com.affine.settings.editorSettings.page.display-bi-link.description": "Display bi-directional links on the doc.",
"com.affine.settings.editorSettings.page.display-bi-link.title": "Display bi-directional links",
"com.affine.settings.editorSettings.page.display-doc-info.description": "Display document information on the doc.",