diff --git a/QtScrcpy/dialog.ui b/QtScrcpy/dialog.ui index e05a5bb..bf6b04b 100644 --- a/QtScrcpy/dialog.ui +++ b/QtScrcpy/dialog.ui @@ -226,7 +226,7 @@ always top - true + false diff --git a/QtScrcpy/inputcontrol/controlevent.cpp b/QtScrcpy/inputcontrol/controlevent.cpp index e745774..4619680 100644 --- a/QtScrcpy/inputcontrol/controlevent.cpp +++ b/QtScrcpy/inputcontrol/controlevent.cpp @@ -48,7 +48,7 @@ void ControlEvent::setScrollEventData(QRect position, qint32 hScroll, qint32 vSc m_data.scrollEvent.vScroll = vScroll; } -void ControlEvent::setCommandEventData(qint32 action) +void ControlEvent::setCommandEventData(ControlEventCommand action) { m_data.commandEvent.action = action; } diff --git a/QtScrcpy/inputcontrol/controlevent.h b/QtScrcpy/inputcontrol/controlevent.h index 6198779..01b0a11 100644 --- a/QtScrcpy/inputcontrol/controlevent.h +++ b/QtScrcpy/inputcontrol/controlevent.h @@ -9,13 +9,11 @@ #include "input.h" #include "keycodes.h" -#define CONTROL_EVENT_COMMAND_BACK_OR_SCREEN_ON 0 - #define TEXT_MAX_CHARACTER_LENGTH 300 // ControlEvent class ControlEvent : public QScrcpyEvent { -public: +public: enum ControlEventType { CET_KEYCODE, CET_TEXT, @@ -23,7 +21,13 @@ public: CET_SCROLL, CET_COMMAND, CET_TOUCH, - }; + }; + + enum ControlEventCommand { + CONTROL_EVENT_COMMAND_BACK_OR_SCREEN_ON = 0, + CONTROL_EVENT_COMMAND_EXPAND_NOTIFICATION_PANEL, + CONTROL_EVENT_COMMAND_COLLAPSE_NOTIFICATION_PANEL, + }; ControlEvent(ControlEventType controlEventType); @@ -35,7 +39,7 @@ public: // position action动作对应的位置 void setTouchEventData(quint32 id, AndroidMotioneventAction action, QRect position); void setScrollEventData(QRect position, qint32 hScroll, qint32 vScroll); - void setCommandEventData(qint32 action); + void setCommandEventData(ControlEvent::ControlEventCommand action); QByteArray serializeData(); @@ -72,7 +76,7 @@ private: qint32 vScroll; } scrollEvent; struct { - qint32 action; + ControlEventCommand action; } commandEvent; }; diff --git a/QtScrcpy/toolform.cpp b/QtScrcpy/toolform.cpp index 60c2b21..1da83bf 100644 --- a/QtScrcpy/toolform.cpp +++ b/QtScrcpy/toolform.cpp @@ -38,6 +38,7 @@ void ToolForm::initStyle() IconHelper::Instance()->SetIcon(ui->volumeUpBtn, QChar(0xf028), 15); IconHelper::Instance()->SetIcon(ui->volumeDownBtn, QChar(0xf027), 15); IconHelper::Instance()->SetIcon(ui->turnOnBtn, QChar(0xf09c), 15); + IconHelper::Instance()->SetIcon(ui->expandNotifyBtn, QChar(0xf103), 15); } void ToolForm::mousePressEvent(QMouseEvent *event) @@ -133,3 +134,10 @@ void ToolForm::on_turnOnBtn_clicked() m_videoForm->postTurnOn(); } } + +void ToolForm::on_expandNotifyBtn_clicked() +{ + if (m_videoForm) { + m_videoForm->expandNotificationPanel(); + } +} diff --git a/QtScrcpy/toolform.h b/QtScrcpy/toolform.h index 5e2ace6..8aec54c 100644 --- a/QtScrcpy/toolform.h +++ b/QtScrcpy/toolform.h @@ -46,6 +46,8 @@ private slots: void on_turnOnBtn_clicked(); + void on_expandNotifyBtn_clicked(); + private: void initStyle(); diff --git a/QtScrcpy/toolform.ui b/QtScrcpy/toolform.ui index 5cb5d26..ee679a0 100644 --- a/QtScrcpy/toolform.ui +++ b/QtScrcpy/toolform.ui @@ -43,6 +43,16 @@ + + + + expand notify + + + + + + diff --git a/QtScrcpy/videoform.cpp b/QtScrcpy/videoform.cpp index bae531a..ae3e425 100644 --- a/QtScrcpy/videoform.cpp +++ b/QtScrcpy/videoform.cpp @@ -340,7 +340,27 @@ void VideoForm::postTurnOn() if (!controlEvent) { return; } - controlEvent->setCommandEventData(CONTROL_EVENT_COMMAND_BACK_OR_SCREEN_ON); + controlEvent->setCommandEventData(ControlEvent::CONTROL_EVENT_COMMAND_BACK_OR_SCREEN_ON); + m_inputConvert.sendControlEvent(controlEvent); +} + +void VideoForm::expandNotificationPanel() +{ + ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_COMMAND); + if (!controlEvent) { + return; + } + controlEvent->setCommandEventData(ControlEvent::CONTROL_EVENT_COMMAND_EXPAND_NOTIFICATION_PANEL); + m_inputConvert.sendControlEvent(controlEvent); +} + +void VideoForm::collapseNotificationPanel() +{ + ControlEvent* controlEvent = new ControlEvent(ControlEvent::CET_COMMAND); + if (!controlEvent) { + return; + } + controlEvent->setCommandEventData(ControlEvent::CONTROL_EVENT_COMMAND_COLLAPSE_NOTIFICATION_PANEL); m_inputConvert.sendControlEvent(controlEvent); } @@ -360,10 +380,9 @@ void VideoForm::staysOnTop(bool top) if (isVisible()) { needShow = true; } - if (top) { - setWindowFlag(Qt::WindowStaysOnTopHint); - } else { - setWindowFlag(Qt::WindowStaysOnTopHint, false); + setWindowFlag(Qt::WindowStaysOnTopHint, top); + if (m_toolForm) { + m_toolForm->setWindowFlag(Qt::WindowStaysOnTopHint, top); } if (needShow) { show(); diff --git a/QtScrcpy/videoform.h b/QtScrcpy/videoform.h index 233451d..c37171c 100644 --- a/QtScrcpy/videoform.h +++ b/QtScrcpy/videoform.h @@ -36,6 +36,8 @@ public: void postVolumeDown(); // turn the screen on if it was off, press BACK otherwise void postTurnOn(); + void expandNotificationPanel(); + void collapseNotificationPanel(); void postTextInput(const QString& text); void staysOnTop(bool top = true); diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlEvent.java b/server/src/main/java/com/genymobile/scrcpy/ControlEvent.java index 039b0f0..2d7c0a3 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ControlEvent.java +++ b/server/src/main/java/com/genymobile/scrcpy/ControlEvent.java @@ -13,6 +13,8 @@ public final class ControlEvent { public static final int TYPE_TOUCH = 5; public static final int COMMAND_BACK_OR_SCREEN_ON = 0; + public static final int COMMAND_EXPAND_NOTIFICATION_PANEL = 1; + public static final int COMMAND_COLLAPSE_NOTIFICATION_PANEL = 2; private int type; private String text; diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java index 96f86e6..c74844e 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Device.java +++ b/server/src/main/java/com/genymobile/scrcpy/Device.java @@ -172,6 +172,14 @@ public final class Device { this.rotationListener = rotationListener; } + public void expandNotificationPanel() { + serviceManager.getStatusBarManager().expandNotificationsPanel(); + } + + public void collapsePanels() { + serviceManager.getStatusBarManager().collapsePanels(); + } + static Rect flipRect(Rect crop) { return new Rect(crop.top, crop.left, crop.bottom, crop.right); } diff --git a/server/src/main/java/com/genymobile/scrcpy/EventController.java b/server/src/main/java/com/genymobile/scrcpy/EventController.java index 2d09fd7..c4f9dff 100644 --- a/server/src/main/java/com/genymobile/scrcpy/EventController.java +++ b/server/src/main/java/com/genymobile/scrcpy/EventController.java @@ -1,6 +1,7 @@ package com.genymobile.scrcpy; import com.genymobile.scrcpy.wrappers.InputManager; +import com.genymobile.scrcpy.wrappers.ServiceManager; import android.graphics.Point; import android.os.SystemClock; @@ -301,6 +302,12 @@ public class EventController { switch (action) { case ControlEvent.COMMAND_BACK_OR_SCREEN_ON: return pressBackOrTurnScreenOn(); + case ControlEvent.COMMAND_EXPAND_NOTIFICATION_PANEL: + device.expandNotificationPanel(); + return true; + case ControlEvent.COMMAND_COLLAPSE_NOTIFICATION_PANEL: + device.collapsePanels(); + return true; default: Ln.w("Unsupported command: " + action); } diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/ServiceManager.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/ServiceManager.java index 2d98d0a..3bcdc0e 100644 --- a/server/src/main/java/com/genymobile/scrcpy/wrappers/ServiceManager.java +++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/ServiceManager.java @@ -14,6 +14,7 @@ public final class ServiceManager { private DisplayManager displayManager; private InputManager inputManager; private PowerManager powerManager; + private StatusBarManager statusBarManager; public ServiceManager() { try { @@ -60,4 +61,11 @@ public final class ServiceManager { } return powerManager; } + + public StatusBarManager getStatusBarManager() { + if (statusBarManager == null) { + statusBarManager = new StatusBarManager(getService("statusbar", "com.android.internal.statusbar.IStatusBarService")); + } + return statusBarManager; + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/StatusBarManager.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/StatusBarManager.java new file mode 100644 index 0000000..28b0258 --- /dev/null +++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/StatusBarManager.java @@ -0,0 +1,41 @@ +package com.genymobile.scrcpy.wrappers; + +//import android.annotation.SuppressLint; +import android.os.IInterface; +//import android.view.InputEvent; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class StatusBarManager { + + private final IInterface manager; + private final Method expandNotificationsPanelMethod; + private final Method collapsePanelsMethod; + + public StatusBarManager(IInterface manager) { + this.manager = manager; + try { + expandNotificationsPanelMethod = manager.getClass().getMethod("expandNotificationsPanel"); + collapsePanelsMethod = manager.getClass().getMethod("collapsePanels"); + } catch (NoSuchMethodException e) { + throw new AssertionError(e); + } + } + + public void expandNotificationsPanel() { + try { + expandNotificationsPanelMethod.invoke(manager); + } catch (InvocationTargetException | IllegalAccessException e) { + throw new AssertionError(e); + } + } + + public void collapsePanels() { + try { + collapsePanelsMethod.invoke(manager); + } catch (InvocationTargetException | IllegalAccessException e) { + throw new AssertionError(e); + } + } +} \ No newline at end of file