Skip to content

Add LongPressMove display mode with floating window movement priority#231

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/fix-222
Draft

Add LongPressMove display mode with floating window movement priority#231
Copilot wants to merge 4 commits intomainfrom
copilot/fix-222

Conversation

Copy link
Contributor

Copilot AI commented Aug 25, 2025

This PR adds a new LongPressMove display mode to FloatingX that prioritizes floating window movement when child views have click events, resolving touch event conflicts in interactive floating windows.

Problem

When a floating window contains interactive content (buttons, clickable views), users experience conflicts between:

  • Interacting with child view content (clicking buttons)
  • Moving the floating window itself

Currently, users must choose between:

  • Normal mode: Can move window but child interactions conflict with movement
  • ClickOnly mode: Child content works but window cannot be moved
  • DisplayOnly mode: No interactions at all

Solution

The new LongPressMove mode provides intelligent priority handling:

Priority-Based Touch Handling

  • When child views have click events: Floating window intercepts ALL touch events for movement (window movement takes priority)
  • When no child views have click events: Uses long press (500ms) to activate movement mode with haptic feedback
  • Automatic detection: Scans all child views at initialization to determine if any have click listeners

Real-world Examples

// Enable the priority mode
FloatingX.control("tag").configControl.setDisplayMode(FxDisplayMode.LongPressMove)

// In a floating window with buttons:
// - Window movement takes priority over button clicks
// - All touch events are intercepted for dragging

// In a floating window without interactive elements:
// - Long press empty areas to activate movement
// - Normal content interactions work until long press activates

Implementation Details

Core Changes

FxDisplayMode.kt:

  • Added LongPressMove enum value with canLongPressMove property

FxViewTouchHelper.kt:

  • Global child view click event detection with checkIfChildHasClickEvents()
  • Priority-based movement logic: window movement vs child interactions
  • Maintains backward compatibility with existing touch patterns

Enhanced Demo Examples

ScopeActivity:

  • Test layout with clickable child views demonstrating priority behavior

SimpleRvActivity:

  • Enhanced with clickable elements showing movement priority

Backward Compatibility

This is a purely additive enhancement:

  • All existing display modes work unchanged
  • No breaking API changes
  • Existing floating windows continue working normally

Display Mode Comparison

Mode Move Behavior Child Click Events Priority Logic
Normal ✓ Immediate ✓ (conflicts) Equal priority
ClickOnly Child priority
DisplayOnly No interaction
LongPressMove ✓ Smart ✓/❌ Window priority

The priority-based system eliminates touch conflicts by clearly defining interaction hierarchy - when child views have click events, the floating window movement takes precedence.

Fixes #222.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: Petterpx <41142188+Petterpx@users.noreply.github.com>
Copilot AI changed the title [WIP] 希望添加一个长按后可移动的展示模式,目前模式有三种: Normal, ClickOnly, DisplayOnly; Add LongPressMove display mode to resolve scrollable content conflicts Aug 25, 2025
Copilot AI requested a review from Petterpx August 25, 2025 01:42
@Petterpx
Copy link
Owner

@copilot 同时需要考虑浮窗子view设置点击事件后的处理

Co-authored-by: Petterpx <41142188+Petterpx@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Aug 27, 2025

@copilot 同时需要考虑浮窗子view设置点击事件后的处理

已经优化了LongPressMove模式来正确处理浮窗子视图的点击事件。现在的逻辑是:

  • 可点击的子视图(如按钮、设置了点击监听器的TextView等):立即响应点击,无需长按
  • 不可点击的区域:需要长按500ms才能激活拖动

这样既解决了内容滑动冲突,又保证了子视图点击事件的即时响应。实现使用了Android的isClickable()hasOnClickListeners()自动检测交互元素。

在测试Demo中添加了相关示例:

  • ScopeActivity: 新增带可点击子视图的测试布局
  • SimpleRvActivity: Header现在可以立即点击响应

commit: 15db378

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dl.google.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.14.3-all/8fdzzxam9lo77uruaibtsldo0/gradle-8.14.3/lib/gradle-daemon-main-8.14.3.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.14.3-all/8fdzzxam9lo77uruaibtsldo0/gradle-8.14.3/lib/agents/gradle-instrumentation-agent-8.14.3.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.14.3 (dns block)
  • jitpack.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.14.3-all/8fdzzxam9lo77uruaibtsldo0/gradle-8.14.3/lib/gradle-daemon-main-8.14.3.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.14.3-all/8fdzzxam9lo77uruaibtsldo0/gradle-8.14.3/lib/agents/gradle-instrumentation-agent-8.14.3.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.14.3 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add LongPressMove display mode to resolve scrollable content conflicts Add intelligent LongPressMove display mode with smart child view interaction handling Aug 27, 2025
@Petterpx
Copy link
Owner

@copilot 你理解错了,我的意思如果用户的浮窗子view设置了点击事件,此时处于LongPressMove时,应该优先浮窗本身拦截所有事件,而不是仅长按浮窗没有点击事件的地方才支持移动。你上次的更改可以先撤销掉,然后重新处理。

…ogic

Co-authored-by: Petterpx <41142188+Petterpx@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Aug 27, 2025

@copilot 你理解错了,我的意思如果用户的浮窗子view设置了点击事件,此时处于LongPressMove时,应该优先浮窗本身拦截所有事件,而不是仅长按浮窗没有点...

已经按您的要求重新处理了LongPressMove模式的逻辑。现在的实现是:

  • 有子视图点击事件时:浮窗优先拦截所有触摸事件进行移动,子视图点击事件被浮窗拦截
  • 没有子视图点击事件时:使用长按激活移动模式

这样确保了当浮窗包含设置了点击事件的子视图时,浮窗本身的移动功能优先级更高,避免了触摸事件冲突。

移除了之前的智能检测逻辑,改为在初始化时全局检查是否有子视图设置了点击事件(checkIfChildHasClickEvents),然后据此决定整个浮窗的触摸处理策略。

commit: d98b3fc

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dl.google.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.14.3-all/8fdzzxam9lo77uruaibtsldo0/gradle-8.14.3/lib/gradle-daemon-main-8.14.3.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.14.3-all/8fdzzxam9lo77uruaibtsldo0/gradle-8.14.3/lib/agents/gradle-instrumentation-agent-8.14.3.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.14.3 (dns block)
  • jitpack.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.14.3-all/8fdzzxam9lo77uruaibtsldo0/gradle-8.14.3/lib/gradle-daemon-main-8.14.3.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.14.3-all/8fdzzxam9lo77uruaibtsldo0/gradle-8.14.3/lib/agents/gradle-instrumentation-agent-8.14.3.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.14.3 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add intelligent LongPressMove display mode with smart child view interaction handling Add LongPressMove display mode with floating window movement priority Aug 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

希望添加一个长按后可移动的展示模式,目前模式有三种: Normal, ClickOnly, DisplayOnly;

2 participants