/*
 * Kylin-video
 *
 * Copyright (C) 2021, Tianjin KYLIN Information Technology Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * Authors: Liu Cong <liucong1@kylinos.cn>
 *
 */

#include "mainwidget.h"
#include "ui_mainwidget.h"

#include <fcntl.h>
#include <QLabel>
#include <QEvent>
#include <QDebug>
#include <QTimer>
#include <QScreen>
#include <QThread>
#include <QMimeData>
#include <QKeyEvent>
#include <QDBusReply>
#include <QGSettings>
#include <QDropEvent>
#include <QCloseEvent>
#include <QMouseEvent>
#include <QFileDialog>
#include <QDBusInterface>
#include <QStandardPaths>
#include <QStackedLayout>
#include <QDesktopWidget>
#include <QDragEnterEvent>
#include <QDBusConnection>
#include <QFileSystemWatcher>
#include <QPropertyAnimation>
#include <ukui-log4qt.h>

#include <KWindowSystem>

#include "kmenu.h"
#include "topwindow.h"
#include "contralbar.h"
#include "dbusadapter.h"
#include "setupdialog.h"
#include "aboutdialog.h"
#include "titlewidget.h"
#include "playglwidget.h"
#include "core/mpvcore.h"
#include "minimodeshade.h"
#include "playlistwidget.h"
#include "mediainfodialog.h"
#include "systemtrayicon.h"

#include "global/global.h"
#include "global/extensions.h"
#include "global/translator.h"
#include "global/globalsignal.h"
#include "global/shortcutsetting.h"

#include "ukui-wayland/ukui-decoration-client.h"
#include "ukui-wayland/ukui-decoration-manager.h"

#include <global/xatom-helper.h>

#include <X11/Xlib.h>
#include <QX11Info>

#include "elog.h"
#define LOG_TAG "mainwidget"

using namespace Global;

MainWidget::MainWidget(QStringList list, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWidget),
    m_normalSize(QSize(0,0)),
    m_inhibitValue(0),
    m_needPlayWhenMin(false),
    m_needPlayWhenS34(false),
    m_isMaxWindow(false),
    m_isScreenLocked(false),
    m_canHideAll(true),
    m_isActive(true),
    m_isMiniMode(false),
    m_firstRemoveBar(true),
    m_moveFlag(true),
    m_exitFlag(false),
    m_contralBar(nullptr),
    m_rightClickMenu(nullptr),
//    m_mediaInfoDialog(nullptr),
//    m_playListWidget(nullptr),
    m_setupDialog(nullptr),
    m_aboutDialog(nullptr),
    m_trayIcon(nullptr)
{
    ui->setupUi(this);

    if(!gsetup->canRunMultiple.first)
        Single(list);
    initDBus();

    translator->load("");
    gshortCut->setParent(this);
    gshortCut->initData();

#if 0
    if(isWayland) {
        installEventFilter(this);
        setMouseTracking(true);
        ui->stackedWidget->setMouseTracking(true);
        ui->widget_dock->setMouseTracking(true);
        ui->home_page->setMouseTracking(true);
    }
    else
#endif
    {
        setAttribute(Qt::WA_TranslucentBackground);
        MotifWmHints hints1;
        hints1.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
        hints1.functions = MWM_FUNC_ALL;
        hints1.decorations = MWM_DECOR_BORDER;
        XAtomHelper::getInstance()->setWindowMotifHint(winId(), hints1);
        move((QApplication::desktop()->screenGeometry(0).width() - this->width()) / 2, (QApplication::desktop()->screenGeometry(0).height() - this->height()) / 2);
    }

    setWindowTitle(tr("Video Player"));
    setAcceptDrops(true);

    initLayout();
//    initContralBar();
//    initTitleWidget();
//    initPlayListWidget();
    initSetupDialog();
    initAboutDialog();
    initCore();
    initMenu();
    initGlobalSig();
    initTrayIcon();
    initConnect();
//    initShowModeAnimation();

    // 需要show出来之后才能播放，不然播放会失败，原因是 QOpenGLWidget 没有 show 的时候渲染会报错。
    QTimer::singleShot(100, [list](){
        if(list.size() > 0)
            g_user_signal->addFiles(list);
    });
}

MainWidget::~MainWidget()
{
    interface->call("Uninhibit", m_inhibitValue);
    log_i("call Uninhibit, cookie is %ld", m_inhibitValue);
    delete m_playWidget;
    m_core->Stop();
    delete ui;
}

void MainWidget::initMenu()
{
    m_rightClickMenu = new KRightClickMenu(this);

    connect(m_rightClickMenu, SIGNAL(sigOpenFile()), this, SLOT(slotOpenFile()));
    connect(m_rightClickMenu, SIGNAL(sigOpenDir()), this, SLOT(slotOpenDir()));
    connect(m_rightClickMenu, SIGNAL(sigOpenUrl()), this, SLOT(slotOpenUrl()));
    connect(m_rightClickMenu, SIGNAL(sigToTop(bool)), this, SLOT(slotToTop(bool)));
    connect(m_rightClickMenu, SIGNAL(sigPlayOrder(int)),this, SLOT(slotPlayOrder(int)));
    connect(m_rightClickMenu, &KRightClickMenu::sigDefaultFrame, [this](){
        m_vAspect = Mpv::AUTO;
    });
    connect(m_rightClickMenu, &KRightClickMenu::sig4Div3Frame, [this](){
        m_vAspect = Mpv::DIV_4_3;
    });
    connect(m_rightClickMenu, &KRightClickMenu::sig16Div9Frame, [this](){
        m_vAspect = Mpv::DIV_16_9;
    });
    connect(m_rightClickMenu, &KRightClickMenu::sigFullFrame, [this](){
        m_vAspect = Mpv::FULL;
        updateAspect();
    });

    connect(m_rightClickMenu, &KRightClickMenu::sigRestoreFrame, [this](){
        m_vAspect = Mpv::AUTO;
    });

    connect(m_rightClickMenu, &KRightClickMenu::sigAlongRotate, [this](){
        // 旋转后需要判断是否时满屏画面，如果是的话需要改变比例
        if(m_vAspect == Mpv::FULL)
            updateAspect();
    });
    connect(m_rightClickMenu, &KRightClickMenu::sigInverseRotate, [this](){
        if(m_vAspect == Mpv::FULL)
            updateAspect();
    });
    connect(m_rightClickMenu, &KRightClickMenu::sigMediaInfo, [this](){
        if(m_playState < 0)
            return;
        // 媒体信息弹窗
        MediaInfoDialog mi(this);
        mi.setModal(true);
        mi.setData(m_core->getMediaInfo());
        connect(g_core_signal, &GlobalCoreSignal::sigFileInfoChange, &mi, [&mi, this](Mpv::FileInfo fi){
            mi.setData(m_core->getMediaInfo());
        });
        mi.show();
        mi.exec();
    });
}

void MainWidget::initLayout()
{
    QFont f("Noto Sans CJK SC Regular");
    f.setPixelSize(16);
//    ui->btn_open->setFont(f);
//    ui->btn_open_dir->setFont(f);

//    setMinimumSize(NormalMinSize);
    resize(NormalMinSize);
    // 设置模糊
    KWindowEffects::enableBlurBehind(winId(), true);

#if 0
    ui->label_name->setText(tr("Video Player"));
    ui->btn_open->setText(tr("open file"));
    ui->btn_open_dir->setText(tr("open dir"));
#endif

    // 播放控件
    m_playWidget = new PlayGLWidget(ui->play_page);
    m_playWidget->setGeometry(0, 0, width(), height());

    m_defaultFrame = new QWidget(m_playWidget);
    m_defaultFrame->setStyleSheet("QWidget{background-color:#000000;}");
    m_defaultFrame->show();
    m_defaultFrame->setMouseTracking(true);

    m_centerLogo = new QWidget(m_defaultFrame);
    m_centerLogo->setFixedSize(CenterLogoSize);

    m_musicFrame = new QWidget(m_playWidget);
    m_musicFrame->setStyleSheet("QWidget{background-color:#262626;}");
    m_musicFrame->setMouseTracking(true);
    m_musicFrame->hide();

    m_musicLogo = new QWidget(m_musicFrame);
    m_musicLogo->installEventFilter(m_musicFrame);
    m_musicLogo->setFixedSize(MusicLogoSize);
    m_musicLogo->setStyleSheet("border-image:url(:/ico/music-background.png);");

    m_osdFrame = new QLabel(m_musicFrame);
    m_osdFrame->installEventFilter(m_musicFrame);
    m_osdFrame->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    m_osdFrame->setStyleSheet("background-color:rgba(0,0,0,0);color:#ffffff;");
    m_osdFrame->hide();
    f.setPixelSize(23);
    m_osdFrame->setFont(f);

    m_osdShowTimer = new QTimer;
    m_osdShowTimer->setInterval(2000);
    connect(m_osdShowTimer, &QTimer::timeout, [this](){m_osdFrame->setText("");m_osdFrame->hide();});

    QHBoxLayout *lo = new QHBoxLayout(m_centerLogo);
    lo->setContentsMargins(0,0,0,0);

    // 初始化上层窗口
    m_topWindow = new TopWindow(this);
    m_topWindow->show();
    connect(m_topWindow, &TopWindow::sigQuit, this, &MainWidget::appQuit);
    connect(m_topWindow, &TopWindow::sigClose, this, &MainWidget::close);
    connect(m_topWindow, &TopWindow::sigMinSize, this, &MainWidget::slotShowMin);


#if 0
    QPushButton *btn_icon = new QPushButton;
    btn_icon = new QPushButton;
    btn_icon->setFixedSize(QSize(65, 65));
    btn_icon->setIconSize(QSize(65, 65));
    btn_icon->setIcon(QIcon::fromTheme("kylin-video"));
    btn_icon->setStyleSheet("QPushButton{border:0px;background:transparent;}"
                            "QPushButton::hover{border:0px;background:transparent;}"
                            "QPushButton::pressed{border:0px;background:transparent;}");

    QLabel *lb_name = new QLabel;
    lo->addStretch();
    lo->addWidget(btn_icon);
    lo->addWidget(lb_name);
    lo->addStretch();
    lb_name->setText(tr("Video Player"));
    lb_name->setStyleSheet("color: rgba(249, 249, 249, 204);font: 57 46px \"Noto Sans CJK SC Medium\";");

    ui->btn_logo->setFixedSize(QSize(70,70));
    ui->btn_logo->setIconSize(QSize(70,70));
    ui->btn_logo->setIcon(QIcon::fromTheme("kylin-video"));
    ui->btn_logo->setStyleSheet("QPushButton{border:0px;background:transparent;}"
                                "QPushButton::hover{border:0px;background:transparent;}"
                                "QPushButton::pressed{border:0px;background:transparent;}");


    ui->btn_open->setCursor(Qt::PointingHandCursor);
    ui->btn_open->setFixedSize(MainButtonSize);
    ui->btn_open->setStyleSheet("QPushButton:!hover{background-color:rgba(255,255,255,19);border-radius:4px;color:rgb(255,255,255);}"
                                "QPushButton:hover{background-color:rgba(255,255,255,25);border-radius:4px;color:rgb(255,255,255);}"
                                "QPushButton:pressed{background-color:rgba(255,255,255,14);border-radius:4px;color:rgb(255,255,255);}");

    ui->btn_open_dir->setCursor(Qt::PointingHandCursor);
    ui->btn_open_dir->setFixedSize(MainButtonSize);
    ui->btn_open_dir->setStyleSheet("QPushButton:!hover{background-color:rgba(255,255,255,19);border-radius:4px;color:rgb(255,255,255);}"
                                    "QPushButton:hover{background-color:rgba(255,255,255,25);border-radius:4px;color:rgb(255,255,255);}"
                                    "QPushButton:pressed{background-color:rgba(255,255,255,14);border-radius:4px;color:rgb(255,255,255);}");

    {
        // mini 模式遮罩初始化
    	if (isWayland)
        	m_miniModeShade = new MiniModeShade(this);
    	else
        	m_miniModeShade = new MiniModeShade(ui->stackedWidget);
        m_miniModeShade->raise();
        m_miniModeShade->hide();
    }
#endif
}

#if 0
void MainWidget::initContralBar()
{
    // 控制栏
    m_contralBar = new ContralBar(ui->play_page);
//    m_contralBar = new ContralBar;
    m_contralBar->setGeometry(120, height()-72, width()-240, 48);
    connect(m_contralBar, &ContralBar::sigCanHide, [this](bool canHide){
         m_canHideAll = canHide;
    });
}
#endif

#if 0
void MainWidget::initTitleWidget()
{
    m_titleMenu = new TitleMenu;
    connect(m_titleMenu, &TitleMenu::sigQuit, this, &MainWidget::close);

    if (isWayland)
        m_titleWidget = new TitleWidget(this);
    else
        m_titleWidget = new TitleWidget(ui->stackedWidget);
    m_titleWidget->raise();
    m_titleWidget->move(0, 0);
    m_titleWidget->setTitle(tr("video player"), false);

    {
        connect(m_miniModeShade, &MiniModeShade::sigPlayPause, [&](){
            if(m_playState == Mpv::Playing)
                m_core->Pause();
            else if(m_playState == Mpv::Paused)
                m_core->Play();
        });
        connect(m_miniModeShade, &MiniModeShade::sigShowNormal, this, &MainWidget::slotShowNormalMode);
        connect(m_miniModeShade, &MiniModeShade::sigClose, this, &MainWidget::close);

        connect(m_titleWidget, &TitleWidget::sigMiniMode, this, &MainWidget::slotShowMiniMode);
    }

    connect(m_titleWidget, &TitleWidget::sigShowMenu, [this](){
        m_titleMenu->exec(QPoint(m_titleWidget->getMenuBtnX()+mapToGlobal(QPoint(0,0)).x(),
                                 mapToGlobal(QPoint(0,0)).y()+m_titleWidget->height()-5));
    });
    connect(m_titleWidget, &TitleWidget::sigMiniSize, this, &MainWidget::slotShowMin);
    connect(m_titleWidget, &TitleWidget::sigMaxSize, this, &MainWidget::slotShowMax);
    connect(m_titleWidget, &TitleWidget::sigDBClicked, this, &MainWidget::slotShowMax);
    connect(m_titleWidget, &TitleWidget::sigClose, [this](){
        if(m_setupDialog->isHidden() && m_aboutDialog->isHidden()/* && m_mediaInfoDialog->isHidden()*/)
        {
            close();
        }
    });
    connect(m_titleWidget, &TitleWidget::sigCanHide, [this](bool canHide){
         m_canHideAll = canHide;
    });
}
#endif

void MainWidget::initSetupDialog()
{
    m_setupDialog = new SetUpDialog(this);
    m_setupDialog->hide();
}

void MainWidget::initAboutDialog()
{
    m_aboutDialog = new AboutDialog(this);
    m_aboutDialog->hide();
}

#if 0
void MainWidget::initPlayListWidget()
{
    if (isWayland)
    	m_playListWidget = new PlayListWidget(this);
    else
        m_playListWidget = new PlayListWidget(ui->stackedWidget);
    connect(m_playListWidget, &PlayListWidget::sigMove, [this](int distance){
        m_titleWidget->setGeometry(0, 0, width() - distance, m_titleWidget->height());
    });

    // 正在播放的文件改变，书签需要刷新
    connect(m_playListWidget->getPlayList(), &PlayList::sigPlayingFileMarkUpdate, [this](QVector<MarkItem> marks){
        m_contralBar->clearMark();
        foreach (MarkItem item, marks) {
            m_contralBar->addMark(item.m_markPos, item.m_describe);
        }
    });

    connect(m_playListWidget->getPlayList(), &PlayList::sigDeleteMark, [this](int mark_pos){
        m_contralBar->deleteMark(mark_pos);
    });

    // 正在播放时插入书签，需要刷新进度条书签
    connect(m_playListWidget->getPlayList(), &PlayList::sigInsertMark, [this](MarkItem mark){
        m_contralBar->insertMark(mark.m_markPos, mark.m_describe);
    });
}
#endif

#if 0
// 初始化模式切换动画 normal -> mini
void MainWidget::initShowModeAnimation()
{
    m_miniAnm = new QPropertyAnimation(this, "size");
//    m_miniAnm->setDuration(300);
    m_miniAnm->setDuration(1);
    m_miniAnm->setEasingCurve(QEasingCurve::OutCubic);
    connect(m_miniAnm, &QPropertyAnimation::finished, [this](){
        this->setFixedSize(size());
        m_miniModeShade->show();
        m_miniModeShade->raise();
        m_miniModeShade->resize(this->size());
    });

    m_normalAnm = new QPropertyAnimation(this, "size");
//    m_normalAnm->setDuration(300);
    m_normalAnm->setDuration(1);
    m_normalAnm->setEasingCurve(QEasingCurve::OutCubic);
    connect(m_normalAnm, &QPropertyAnimation::finished, [this](){
        setMinimumSize(NormalMinSize);
        m_contralBar->setMiniMode(false);
        m_titleWidget->setMiniMode(false);
        m_titleWidget->show();
        m_playListWidget->show();
        update();
    });
}
#endif

void MainWidget::initCore()
{
    m_playState = Mpv::Idle;
    m_core = new MpvCore(m_playWidget);
    connect(m_core, &MpvCore::sigShowText, this, &MainWidget::showText);
}

void MainWidget::initGlobalSig()
{
    connect(g_user_signal, &GlobalUserSignal::sigShowStopFrame, [&](){
        // 当前默认为拼音拼播放界面
        m_musicFrame->show();
    });
    connect(g_user_signal, &GlobalUserSignal::sigExit, this, &MainWidget::close);
    connect(g_user_signal, &GlobalUserSignal::sigPlayWidgetClicked, this, &MainWidget::slotPlayWidgetClicked);
    connect(g_user_signal, &GlobalUserSignal::sigSelectFile, this, &MainWidget::slotOpenFile);
    connect(g_user_signal, &GlobalUserSignal::sigSelectDir, this, &MainWidget::slotOpenDir);
    connect(g_user_signal, &GlobalUserSignal::sigPlayPause, [&](){
        if(m_playState == Mpv::Playing)
            m_core->Pause();
        else if(m_playState == Mpv::Paused)
            m_core->Play();
    });
    connect(g_user_signal, &GlobalUserSignal::sigTheme, this, &MainWidget::slotThemeChange);

    connect(g_user_signal, &GlobalUserSignal::sigRightMenuShow, [&](){
        if(!m_isActive && isWayland)
            return;
        if (QGuiApplication::focusWindow())
            m_rightClickMenu->exec(QCursor::pos(QGuiApplication::focusWindow()->screen()) + QPoint(1,1));
    });

#if 0
    connect(g_user_signal, &GlobalUserSignal::sigShowPlayList, [&](){
        if(!m_playListWidget->isShow() && ui->stackedWidget->currentIndex() == 1) {
            slotHideAll(true);
        }
    });
#endif

    connect(g_core_signal, &GlobalCoreSignal::sigStateChange, this, &MainWidget::slotPlayStateChange);

    connect(g_core_signal, &GlobalCoreSignal::sigFileInfoChange, [&](Mpv::FileInfo fi){
        m_currentFile = fi.file_path;
#if 0
        m_titleWidget->setTitle(fi.file_path.split("/").back());
#endif
    });

    // 直接让 mpvcore 去播放有问题，必须先切换到播放页面
    connect(g_user_signal, &GlobalUserSignal::sigOpen, this, &MainWidget::slotPlayFile);

    connect(g_user_signal, &GlobalUserSignal::sigShowSetup, [&](int index){
        SetUpDialog setup(this);
        setup.setIndex(index);
        setup.move(mapToGlobal(QPoint(0,0)) + QPoint(width()-setup.width(), height()-setup.height())/2);
        setup.show();
        if(isWayland)
        {
            UKUIDecorationManager::getInstance()->removeHeaderBar(setup.windowHandle());
            UKUIDecorationManager::getInstance()->setCornerRadius(setup.windowHandle(), 12, 12, 12, 12);
            m_setupDialog->setFixedSize(setup.size());
        }
        setup.exec();

#if 0
        m_setupDialog->setIndex(index);
        // 显示到应用中间
        m_setupDialog->move(mapToGlobal(QPoint(0,0)) + QPoint(width()-m_setupDialog->width(), height()-m_setupDialog->height())/2);
        m_setupDialog->show();
        if(isWayland)
        {
            UKUIDecorationManager::getInstance()->removeHeaderBar(m_setupDialog->windowHandle());
            UKUIDecorationManager::getInstance()->setCornerRadius(m_setupDialog->windowHandle(), 12, 12, 12, 12);
            m_setupDialog->setFixedSize(m_setupDialog->size());
        }
        m_setupDialog->exec();
#endif
    });

    connect(g_user_signal, &GlobalUserSignal::sigShowAbout, [&](){
        m_aboutDialog->show();
        if(isWayland)
        {
            UKUIDecorationManager::getInstance()->removeHeaderBar(m_aboutDialog->windowHandle());
            UKUIDecorationManager::getInstance()->setCornerRadius(m_aboutDialog->windowHandle(), 12, 12, 12, 12);
            m_aboutDialog->setFixedSize(m_aboutDialog->size());
        }
    });
}

void MainWidget::initConnect()
{
#if 0
    connect(ui->stackedWidget, &QStackedWidget::currentChanged, [&](int index){
        // 不管页面怎么切换，播放列表界面都要再最前面
        m_playListWidget->raise();
        if(index == 0)
            m_titleWidget->setHomePage(true);
        else
            m_titleWidget->setHomePage(false);
    });

    connect(m_contralBar, &ContralBar::sigFullScreen, this, [&](bool full){
        if(full)
        {
            if(windowState() == Qt::WindowMaximized)
                m_isMaxWindow = true;
            else if(windowState() == Qt::WindowNoState)
                m_isMaxWindow = false;
            showFullScreen();
            // 全屏之后设置最大化最小化不可用
            m_titleWidget->setButtonState(false);
        }
        else
        {
            // 全屏直接 showMaximized 不生效，只能先还原之后再最大化（原因未知）
            showNormal();
            if(m_isMaxWindow)
                showMaximized();
            m_titleWidget->setButtonState(true);
        }
    });

    connect(ui->btn_open, &QPushButton::clicked, this, &MainWidget::slotOpenFile);
    connect(ui->btn_open_dir, &QPushButton::clicked, this, &MainWidget::slotOpenDir);
#endif
}

void MainWidget::initTrayIcon()
{
    m_trayIcon = new SystemTrayIcon(this);
    connect(m_trayIcon, &SystemTrayIcon::sigQuit, this, &MainWidget::appQuit);
    connect(m_trayIcon, &SystemTrayIcon::activated, [&](QSystemTrayIcon::ActivationReason reason){
        switch (reason) {
        case QSystemTrayIcon::Trigger:
            if (isHidden()) {
                show();
                QTimer::singleShot(300, [this](){
                    activateWindow();
                    m_topWindow->show();
                });
            }
            else if (!isActiveWindow()) {
                activateWindow();
            }
            break;
        default:
            break;
        }
    });
    m_trayIcon->show();
}

void MainWidget::initDBus()
{

    interface = new QDBusInterface("org.gnome.SessionManager",
                                   "/org/gnome/SessionManager",
                                   "org.gnome.SessionManager",
                                   QDBusConnection::sessionBus());

    QDBusConnection sessionBus = QDBusConnection::sessionBus();
    if(sessionBus.registerService("org.ukui.kylinvideo"))
    {
        sessionBus.registerObject("/org/ukui/kylinvideo",this,
                                  QDBusConnection::ExportAllContents);
        qDebug()<<"初始化DBUS成功";
    }
    else
    {
        log_e("init dbus error");
        qDebug()<<"初始化DBUS失败";
    }
    //S3 S4策略
    QDBusConnection::systemBus().connect(QString("org.freedesktop.login1"),
                                         QString("/org/freedesktop/login1"),
                                         QString("org.freedesktop.login1.Manager"),
                                         QString("PrepareForShutdown"), this,
                                         SLOT(onPrepareForShutdown(bool)));
    QDBusConnection::systemBus().connect(QString("org.freedesktop.login1"),
                                         QString("/org/freedesktop/login1"),
                                         QString("org.freedesktop.login1.Manager"),
                                         QString("PrepareForSleep"), this,
                                         SLOT(onPrepareForSleep(bool)));

    // 锁屏
    QDBusConnection::sessionBus().connect(QString("org.ukui.ScreenSaver"),
                                         QString("/"),
                                         QString("org.ukui.ScreenSaver"),
                                         QString("lock"), this,
                                         SLOT(onScreenLock()));
    QDBusConnection::sessionBus().connect(QString("org.ukui.ScreenSaver"),
                                         QString("/"),
                                         QString("org.ukui.ScreenSaver"),
                                         QString("unlock"), this,
                                         SLOT(onScreenUnlock()));

    // 耳机插拔
    QDBusConnection::sessionBus().connect(QString(""),
                                         QString("/"),
                                         QString("org.ukui.media"),
                                         QString("DbusSingleTest"), this,
                                         SLOT(inputDeviceGet(QString)));


    // 线控
    QDBusConnection::systemBus().connect(QString(),
                                         QString("/"),
                                         QString("com.monitorkey.interface"),
                                         QString("monitorkey"), this,
                                         SLOT(onWiredControl(QString)));



    DbusAdapter *dbs_adapter = new DbusAdapter; // new 出来就行，其他时候这个没用，初始化一下就行，控制都是全局的
}

void MainWidget::appQuit()
{
    // 判断退出时是否需要清空播放列表
    if(gsetup->clearListWhenExit.first)
        g_user_signal->clearPlayList();
    m_exitFlag = true;
    if (m_playState < 0) {
        exit(0);
    }
    m_core->Stop();
}

void MainWidget::onWiredControl(QString str)
{
    int key = str.split(':').first().toInt();
    int num = str.split(':').last().toInt();
    if(num == 1)
        g_user_signal->play_pause();
    else if(num == 2 || key == 163)
        g_user_signal->playNext(true);
    else if(num == 3 || key == 165)
        g_user_signal->playPrev(true);
}

/** ************************************************************************
 * S3 处理
 * @param :isSleep - true  : 进入睡眠
 *                   false : 睡眠唤醒
 *      说明 : s3/s4时暂停播放，同时判断是否锁屏，设置锁屏标志位。当s3/s4唤醒时，通过标
 * 志位判断是否锁屏，如果锁屏了则不做处理，等解锁后继续播放，如果没有锁屏的话直接继续播放。
 ***************************************************************************/
void MainWidget::onPrepareForSleep(bool isSleep)
{
    if(isSleep && m_playState==Mpv::Playing && m_needPlayWhenS34 == false)
    {
        m_core->Pause();
        if(gsetup->keepStateWhenWakeup.first)
            m_needPlayWhenS34 = true;
    }
    else if(!isSleep && m_needPlayWhenS34)
    {
        // 判断是否锁屏了，如果锁屏等解锁后再播放
        if(m_isScreenLocked)
            return;
        m_core->Play();
        m_needPlayWhenS34 = false;
    }
}

/** ************************************************************************
 * S4 处理
 * 说明 : 同上
 ***************************************************************************/
void MainWidget::onPrepareForShutdown(bool Shutdown)
{
    if(Shutdown && m_playState==Mpv::Playing && m_needPlayWhenS34 == false)
    {
        m_core->Pause();
        if(gsetup->keepStateWhenWakeup.first)
            m_needPlayWhenS34 = true;
    }
    else if(!Shutdown && m_needPlayWhenS34)
    {
        // 判断是否锁屏了，如果锁屏等解锁后再播放
        if(m_isScreenLocked)
            return;
        m_core->Play();
        m_needPlayWhenS34 = false;
    }
}

/** ************************************************************************
 * 锁屏处理（如果播放则暂停，和S3S4共用变量，要防止冲突）
 ***************************************************************************/
void MainWidget::onScreenLock()
{
    m_isScreenLocked = true;
    // 只有 wanland 才需要如此
    gshortCut->makeAllInvalid();
    if(m_playState==Mpv::Playing && m_needPlayWhenS34 == false)
    {
        m_core->Pause();
        if(gsetup->keepStateWhenWakeup.first)
            m_needPlayWhenS34 = true;
    }
}

void MainWidget::onScreenUnlock()
{
    m_isScreenLocked = false;
    gshortCut->makeAllValid();
    if(m_needPlayWhenS34)
    {
        m_core->Play();
        if(gsetup->keepStateWhenWakeup.first)
            m_needPlayWhenS34 = false;
    }
}

void MainWidget::inputDeviceGet(QString _device)
{
    // 接收到耳机插拔信号就暂停
    if(m_playState == Mpv::Playing)
        m_core->Pause();
}

void MainWidget::slotToTop(bool is_top)
{
    if(!isWayland)
    {
        Display *display = QX11Info::display();
        XEvent event;
        event.xclient.type = ClientMessage;
        event.xclient.serial = 0;
        event.xclient.send_event = True;
        event.xclient.display = display;
        event.xclient.window  = winId();
        event.xclient.message_type = XInternAtom (display, "_NET_WM_STATE", False);
        event.xclient.format = 32;

        event.xclient.data.l[0] = is_top;
        event.xclient.data.l[1] = XInternAtom (display, "_NET_WM_STATE_ABOVE", False);
        event.xclient.data.l[2] = 0; //unused.
        event.xclient.data.l[3] = 0;
        event.xclient.data.l[4] = 0;

        XSendEvent(display, DefaultRootWindow(display), False,
                   SubstructureRedirectMask|SubstructureNotifyMask, &event);
    }
    else
    {
        PlasmaShellManager::getInstance()->setAppWindowKeepAbove(is_top);
        return;
    }
}

void MainWidget::slotThemeChange(int theme)
{
    switch (theme) {
    case 0:
        g_settings->setValue("General/follow_system_theme", true);
        break;
    case 1:
        g_settings->setValue("General/follow_system_theme", false);
        g_settings->setValue("General/theme", 0);
        break;
    case 2:
        g_settings->setValue("General/follow_system_theme", false);
        g_settings->setValue("General/theme", 1);
        break;
    default:
        break;
    }
}

void MainWidget::slotPlayWidgetClicked()
{
#if 0
    if(m_playListWidget->isShow())
        m_playListWidget->slotHide();
    else
#endif
    {
        if(m_playState == Mpv::Playing)
            m_core->Pause();
        else if(m_playState == Mpv::Paused)
            m_core->Play();
    }
}

void MainWidget::slotOpenFile()
{
    Extensions e;
    QString last_path = g_settings->value("History/last_path").toString();
    if(last_path == "")
        last_path = QDir::homePath();
    QStringList files;

    {
        QFileDialog fd(this);
        fd.setModal(true);
        QList<QUrl> list = fd.sidebarUrls();
        int sidebarNum = 8;
        QString home = QDir::homePath().section("/", -1, -1);
        QString mnt = "/media/" + home + "/";
        QDir mntDir(mnt);
        mntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
        QFileInfoList filist = mntDir.entryInfoList();
        QList<QUrl> mntUrlList;
        for(int i=0; i < sidebarNum && i < filist.size(); i++) {
            QFileInfo fi = filist.at(i);
            //华为990、9a0需要屏蔽最小系统挂载的目录
            if (fi.fileName() == "2691-6AB8")
                 continue;
            mntUrlList << QUrl("file://" + fi.filePath());
        }
        QFileSystemWatcher fsw(&fd);
        fsw.addPath("/media/" + home + "/");
        connect(&fsw, &QFileSystemWatcher::directoryChanged, &fd, [=, &sidebarNum, &mntUrlList, &list, &fd](const QString path){
            QDir wmnDir(path);
            wmnDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
            QFileInfoList wfilist = wmnDir.entryInfoList();
            mntUrlList.clear();
            for(int i=0; i < sidebarNum && i < wfilist.size(); ++i) {
                QFileInfo fi = wfilist.at(i);
                //华为990、9a0需要屏蔽最小系统挂载的目录
                if (fi.fileName() == "2691-6AB8")
                     continue;
                mntUrlList << QUrl("file://" + fi.filePath());
            }
            qDebug() << list + mntUrlList;
            fd.setSidebarUrls(list + mntUrlList);
            fd.update();
        });
        connect(&fd, &QFileDialog::finished, &fd, [=, &list, &fd](){
            fd.setSidebarUrls(list);
        });
        fd.setSidebarUrls(list + mntUrlList);
        fd.setDirectory(QDir(last_path));
        fd.setWindowTitle(tr("Video Player Choose a file"));
        fd.setNameFilters(QStringList() <<
                          tr("Multimedia") + e.allPlayable().forFilter()+";;" <<
                          tr("Video") + e.video().forFilter()+";;" <<
                          tr("Audio") + e.audio().forFilter()+";;");
        fd.setFileMode(QFileDialog::ExistingFiles);

        gshortCut->makeAllInvalid();
        if(fd.exec() == QFileDialog::Accepted)
        {
            files = fd.selectedFiles();
            qDebug() << files;
        }
        gshortCut->makeAllValid();
    }

    if(files.size() <= 0)
        return;
    g_settings->setValue("History/last_path", files.first().left(files.first().lastIndexOf('/') + 1));

    g_user_signal->addFiles(files);
}

void MainWidget::slotOpenDir()
{
    QString last_path = g_settings->value("History/last_path").toString();
    // 打开文件夹
    QString url;

    {
        QFileDialog fd(this);
        fd.setModal(true);
        QList<QUrl> list = fd.sidebarUrls();
        int sidebarNum = 8;
        QString home = QDir::homePath().section("/", -1, -1);
        QString mnt = "/media/" + home + "/";
        QDir mntDir(mnt);
        mntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
        QFileInfoList filist = mntDir.entryInfoList();
        QList<QUrl> mntUrlList;
        for(int i=0; i < sidebarNum && i < filist.size(); i++) {
            QFileInfo fi = filist.at(i);
            //华为990、9a0需要屏蔽最小系统挂载的目录
            if (fi.fileName() == "2691-6AB8")
                 continue;
            mntUrlList << QUrl("file://" + fi.filePath());
        }
        QFileSystemWatcher fsw(&fd);
        fsw.addPath("/media/" + home + "/");
        connect(&fsw, &QFileSystemWatcher::directoryChanged, &fd, [=, &sidebarNum, &mntUrlList, &list, &fd](const QString path){
            QDir wmnDir(path);
            wmnDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
            QFileInfoList wfilist = wmnDir.entryInfoList();
            mntUrlList.clear();
            for(int i=0; i < sidebarNum && i < wfilist.size(); ++i) {
                QFileInfo fi = wfilist.at(i);
                //华为990、9a0需要屏蔽最小系统挂载的目录
                if (fi.fileName() == "2691-6AB8")
                     continue;
                mntUrlList << QUrl("file://" + fi.filePath());
            }
            qDebug() << list + mntUrlList;
            fd.setSidebarUrls(list + mntUrlList);
            fd.update();
        });
        connect(&fd, &QFileDialog::finished, &fd, [=, &list, &fd](){
            fd.setSidebarUrls(list);
        });
        fd.setSidebarUrls(list + mntUrlList);
        fd.setDirectory(QDir(last_path));
        fd.setWindowTitle(tr("Video Player Choose a directory"));
        fd.setFileMode(QFileDialog::DirectoryOnly);

        gshortCut->makeAllInvalid();
        if(fd.exec() == QFileDialog::Accepted)
        {
            url = fd.selectedUrls().at(0).toString();
            if(url.startsWith("file")) {
                url.remove(0, 7);
            }
        }
        gshortCut->makeAllValid();
    }

    if (!url.isEmpty()) {
        g_user_signal->addDir(url);
    }
    g_settings->setValue("History/last_path", url);
}

void MainWidget::slotPlayFile(QString file, int pos)
{
    if(file == QString())
    {
        return;
    }
    // 需要先切换为播放页面，不然播放不出来
    ui->stackedWidget->setCurrentWidget(ui->play_page);
//    slotHideAll(true);

#if 0
    if (!isWayland) {
        m_titleWidget->raise();
    }
#endif
    // 判断是否自动加载字幕
    QStringList subs = QStringList();
    if(gsetup->loadAllSubInDir.first || gsetup->loadSameNameSub.first)
    {
//        QString sub_dir = file.left(file.lastIndexOf("/"));
        QString sub_dir = gsetup->subDir.first;
        Extensions e;
        QRegExp rx_ext(e.subtitles().forRegExp());
        rx_ext.setCaseSensitivity(Qt::CaseInsensitive);
        QStringList dir_list = QDir(sub_dir).entryList();
        QString filename;
        if(gsetup->loadAllSubInDir.first)
        {
            // 加载所有字幕
            QStringList::Iterator it = dir_list.begin();
            while( it != dir_list.end() ) {
                filename = sub_dir;
                if (filename.right(1)!="/") filename += "/";
                filename += (*it);
                QFileInfo fi(filename);
                if (!fi.isDir()) {
                    if (rx_ext.indexIn(fi.suffix()) > -1)
                        subs << filename;
                }
                ++it;
            }
        }
        else if(gsetup->loadSameNameSub.first)
        {
            // 加载文件夹下同名字幕
            QStringList::Iterator it = dir_list.begin();
            while( it != dir_list.end() ) {
                filename = sub_dir;
                if (filename.right(1)!="/") filename += "/";
                filename += (*it);
                QFileInfo fi(filename);
                if (!fi.isDir()) {
                    if (rx_ext.indexIn(fi.suffix()) > -1 && file.left(file.lastIndexOf("."))==filename.left(filename.lastIndexOf(".")))
                        subs << filename;
                }
                ++it;
            }
        }
    }
    m_core->Open(file, pos);
    m_core->AddSubs(subs);
}

void MainWidget::slotPlayStateChange(Mpv::PlayState state)
{
    m_playState = state;
    if(state > 0)
        ui->stackedWidget->setCurrentWidget(ui->play_page);
#if 0
    else
        m_titleWidget->setTitle(tr("video player"), false);
#endif

    // 停止之后画面比例还原（如果需要保持比例需要重新做功能）
    if(m_playState < 0)
        m_vAspect = Mpv::AUTO;

    if(m_playState == Mpv::Playing || m_playState == Mpv::Paused)
    {
        if(m_core->getVid() >= 0) {
            m_defaultFrame->hide();
            m_musicFrame->hide();
//            m_musicLogo->hide();
        }
        else {
            m_defaultFrame->show();
            m_musicFrame->show();
//            m_musicLogo->show();
        }
    }
    else {
        m_defaultFrame->show();
//        m_musicFrame->show();
//        m_musicLogo->show();
    }

    // 如果正在播放，阻止锁屏
    if(!interface->isValid())
    {
        log_e("org.gnome.SessionManager is invalid!");
        return;
    }
    if(m_playState == Mpv::Playing)
    {
        QDBusMessage reply = interface->call(QDBus::Block, "Inhibit", "kylin-video", (quint32)0, "video is playing", (quint32)8);
        m_inhibitValue = reply.arguments().takeFirst().toUInt();
        log_i("call Inhibit, cookie is %ld", m_inhibitValue);
    }
    else
    {
        interface->call("Uninhibit", m_inhibitValue);
        log_i("call Uninhibit, cookie is %ld", m_inhibitValue);
    }

#if 0
    if(state == Mpv::Started)
    {
        // 从上次停止位置播放功能
        if(gsetup->playLastPos.first)
        {
            int resumeTime = g_sqlite->getLastTime(m_currentFile);
            if (resumeTime > 0)
                m_core->Seek(resumeTime);
        }
    }
#endif

    if (state == Mpv::Idle && m_exitFlag) {
        exit(0);
    }
}

#if 0
void MainWidget::slotHideAll(bool is_hide)
{
    if(is_hide)
    {
        if(m_canHideAll)
        {
            m_contralBar->setHide();
            m_titleWidget->setHide();
            if (!m_playListWidget->isShow())
                m_playListWidget->setShowButton(false);
            // 播放列表是否需要隐藏 ?
        }
        else
        {
            // 鼠标要显示出来
            setCursor(Qt::ArrowCursor);
            m_playWidget->setCursor(Qt::ArrowCursor);
            m_titleWidget->setCursor(Qt::ArrowCursor);
        }
    }
    else
    {
        if (!m_playListWidget->isShow()) {
            m_contralBar->setShow();
            m_titleWidget->setShow();
            m_playListWidget->setShowButton(true);
        }
    }
}
#endif

void MainWidget::slotShowMin()
{
#if 0
    // 最小化的时候隐藏播放列表
    m_playListWidget->slotHide();
#endif
    showMinimized();
}

void MainWidget::slotShowMax()
{
    if(isFullScreen())
    {
        g_user_signal->fullScreen();
    }
    // 最大化然后更新图标
    else if(isMaximized())
    {
        showNormal();
        m_titleWidget->updateMaxButtonStatus(false);
    }
    else
    {
        m_normalSize = size();
        showMaximized();
        m_titleWidget->updateMaxButtonStatus(true);
    }
}

#if 0
void MainWidget::slotShowNormalMode()
{
    if(!m_isMiniMode)
        return;
    m_isMiniMode = false;
    m_miniAnm->stop();
    m_miniModeShade->hide();
    setMaximumSize(99999, 99999);
    m_normalAnm->setStartValue(size());
    m_normalAnm->setEndValue(m_normalSize);
    m_normalAnm->start();
    m_normalSize = QSize(0,0);
    m_playWidget->setMouseUsed(true);
}

void MainWidget::slotShowMiniMode()
{
    // 如果是主窗口的话无法进入 mini 模式
    // 如果是全屏的话也无法进入 mini 模式
    if(/*ui->stackedWidget->currentIndex() == 0 || */isFullScreen() || m_isMiniMode)
        return;
    // 如果是最大化的话先退出最大化
    if(isMaximized())
    {
        showNormal();
        m_titleWidget->updateMaxButtonStatus(false);
    }
    // mini 模式窗口大小改变，保留三个按钮，其他全部隐藏
    // 先隐藏，后变化，最后显示按钮
    m_isMiniMode = true;
    if(m_normalSize == QSize(0,0))
        m_normalSize = size();

    setMinimumSize(MiniModeSize);
    m_contralBar->setMiniMode(true);
    m_titleWidget->setMiniMode(true);
    m_titleWidget->hide();
    m_contralBar->hide();
    m_playListWidget->hide();

    m_normalAnm->stop();
    m_miniAnm->setStartValue(size());
    m_miniAnm->setEndValue(minimumSize());
    m_miniAnm->start();
    m_playWidget->setMouseUsed(false);
}
#endif

void MainWidget::ukuiMove()
{
    if(isWayland)
    {
        m_moveFlag = false;
        UKUIDecorationManager::getInstance()->moveWindow(this->windowHandle());
    }
}

void MainWidget::updateAspect()
{
    double s;
    if(m_core->getRotate() / 90 % 2 == 0)
        s = (double)width() / (double)height();
    else
        s = (double)height() / (double)width();
    m_core->SetAspect(QString::number(s));
}

void MainWidget::kylin_video_play_request(QStringList filelist)
{
    // 此处相当于双击打开，需要active一下
    if (isHidden()) {
        show();
        QTimer::singleShot(200, [this](){
            setWindowState(Qt::WindowActive);
            m_topWindow->show();
        });
    }
    else if (!isActiveWindow()) {
        KWindowSystem::setState(winId(), NET::KeepAbove);
        QTimer::singleShot(200, [this](){
            activateWindow();
            KWindowSystem::clearState(winId(), NET::KeepAbove);
        });
    }
    if(filelist.size() > 0)
        g_user_signal->addFiles(filelist);
}

void MainWidget::Single(QStringList filelist)
{
    QStringList homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation);
    QString lockPath = homePath.at(0) + "/.config/kylin-video-lock";
    int fd = open(lockPath.toUtf8().data(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);

    if (fd < 0) { exit(1); }
    if (lockf(fd, F_TLOCK, 0))
    {
        QDBusInterface interface( "org.ukui.kylinvideo",
                                  "/org/ukui/kylinvideo",
                                  "org.ukui.kylinvideo.play",
                                  QDBusConnection::sessionBus());
        QDBusReply<int> reply = interface.call( "kylin_video_play_request", filelist);
        qDebug() << "file path is " << filelist;
        if ( reply.isValid() && reply.value() == 0)
        {
            KyInfo() << "call kylin_video_play_request ok";
        }
        else
        {
            KyInfo() << "fail";
        }
        log_i("The app is already running");
        exit(0);
    }
}

//  osd 显示，如果是没有视频流的话要这样显示
void MainWidget::showText(QString text)
{
    m_osdShowTimer->stop();
    m_osdFrame->setText(text);
    m_osdFrame->show();
    m_osdFrame->raise();
    m_osdShowTimer->start();
}

void MainWidget::resizeEvent(QResizeEvent *event)
{
    if (m_firstRemoveBar && size() == QSize(966, 573))
    {
        resize(minimumSize());
        m_firstRemoveBar = false;
    }

#if 0
    if (m_titleWidget)
    {
        m_titleWidget->resize(width(), m_titleWidget->height());
    }

    if (m_contralBar)
    {
        m_contralBar->setGeometry(120, height()-72, width()-240, 48);
        m_contralBar->setPreviewSize(size());
    }
#endif

    if (m_playWidget) {
        m_playWidget->setGeometry(0, 0, width(), height());
    }

    if (m_defaultFrame)
    {
        m_defaultFrame->setGeometry(0, 0, width(), height());
    }

    if (m_centerLogo) {
        m_centerLogo->move((width() - m_centerLogo->width()) / 2, (height() - m_centerLogo->height()) * 2 / 5);
    }

    if (m_musicFrame) {
        m_musicFrame->setGeometry(0, 0, width(), height());
    }

    if (m_musicLogo) {
        m_musicLogo->move((width() - m_musicLogo->width()) / 2, (height() - m_musicLogo->height()) * 3 / 7);
    }

    if (m_osdFrame) {
        m_osdFrame->setGeometry(25, 55, width() - 40, height() - 50);
    }

    ui->stackedWidget->move(0, 0);
    ui->stackedWidget->resize(size());

    ui->widget_dock->setGeometry(QRect(0, 0, width(), height()));

#if 0
    // 只要大小改变，播放列表都要隐藏起来
    m_playListWidget->move(width() - 16, 0);
    m_playListWidget->resize(m_playListWidget->width(), height());
    m_playListWidget->updateHideIcon();
#endif

    // 如果画面是满屏的话，需要每次改变大小都设置比例
    // (此方法会导致只有在修改完大小之后画面才能改变，没办法实时改变，需查看如果将 no-keepaspect 参数设置上去)
    if(m_vAspect == Mpv::FULL)
        updateAspect();

    // 大小变化的时候 osd 要重新显示
    if(m_playState > 0 && m_playState <= Mpv::Paused)
        m_core->ShowText("");

    QWidget::resizeEvent(event);
}

bool MainWidget::event(QEvent *event)
{
    if(isWayland)
    {
        // 如果是 wayland 环境的话需要通过 active + m_needPlayWhenMin 判断是否需要播放
        if(event->type() == QEvent::WindowActivate)
        {
            if(m_needPlayWhenMin)
            {
                m_core->Play();
                m_needPlayWhenMin = false;
            }
            m_isActive = true;
        }
        else if(event->type() == QEvent::WindowDeactivate)
        {
            m_isActive = false;
        }
    }
    else
    {
        if (event->type() == QEvent::Show) {
            m_topWindow->show();
            if (m_needPlayWhenMin) {
                m_core->Play();
                m_needPlayWhenMin = false;
            }
        }
        else if(event->type() == QEvent::Hide && gsetup->pauseWhenMini.first && m_playState == Mpv::Playing) {
            m_core->Pause();
            m_needPlayWhenMin = true;
        }
    }
    return QWidget::event(event);
}

void MainWidget::mousePressEvent(QMouseEvent *event)
{
    // 主界面也能右键呼出菜单
    if(event->buttons() == Qt::RightButton)
    {
        if(!m_isActive && isWayland)
            return;
        if (QGuiApplication::focusWindow() != nullptr)
            m_rightClickMenu->exec(QCursor::pos(QGuiApplication::focusWindow()->screen()) + QPoint(1,1));
    }
}

#if 1
void MainWidget::showEvent(QShowEvent *event)
{
    QWidget::showEvent(event);
}
#endif

void MainWidget::closeEvent(QCloseEvent *event)
{
    // 关闭的时候最小化到系统托盘 就是隐藏了就行
    if(gsetup->miniToTray.first)
    {
        // 隐藏的时候有必要还原大小，不然再次显示会有问题
        showNormal();
        m_topWindow->showNormal();

        event->ignore();
        m_topWindow->setHide();
        hide();
        return;
    }

    // 判断退出时是否需要清空播放列表
    if(gsetup->clearListWhenExit.first)
        g_user_signal->clearPlayList();
    m_core->Stop();
    QThread::usleep(100000);

    // 关闭之前取消阻止锁屏
    log_i("call Uninhibit, cookie is %ld", m_inhibitValue);
    interface->call("Uninhibit", m_inhibitValue);
    QWidget::closeEvent(event);
    exit(0);
}

void MainWidget::keyPressEvent(QKeyEvent *event)
{
    // 按 esc 退出全屏
    if(event->key() == Qt::Key_Escape) {
        if(isFullScreen())
            g_user_signal->fullScreen();
    }
    else if(event->key() == Qt::Key_F1) {
        // 帮助手册 先就分开写吧，快捷键不生效不知道为啥
        QDBusMessage m = QDBusMessage::createMethodCall("com.kylinUserGuide.hotel_1000",
                                                        "/",
                                                        "com.guide.hotel",
                                                        "showGuide");
        m << "kylin-video";
        if(QDBusConnection::sessionBus().isConnected())
            QDBusConnection::sessionBus().call(m);
    }
}

bool MainWidget::eventFilter(QObject *watched, QEvent *event)
{
    if(isWayland)
    {
        if(watched == this)
        {
            if (event->type() == QEvent::MouseMove){
                auto mouseEvent = static_cast<QMouseEvent *>(event);
                if (mouseEvent->buttons() & Qt::LeftButton) {
                    if(m_moveFlag)
                        ukuiMove();
                }
            }
            else if (event->type() == QEvent::MouseButtonRelease) {
                // 移动之后不要再移动
                m_moveFlag = true;
            }
        }
    }
    return false;
}

void MainWidget::dragEnterEvent(QDragEnterEvent *event)
{
    event->acceptProposedAction();
}

void MainWidget::dropEvent(QDropEvent *event)
{
    QList<QUrl> listUrl = event->mimeData()->urls();
    QStringList filelist;
    Extensions e;
    QRegExp rx_video(e.video().forRegExp());
    QRegExp rx_audio(e.audio().forRegExp());
    rx_video.setCaseSensitivity(Qt::CaseInsensitive);
    rx_audio.setCaseSensitivity(Qt::CaseInsensitive);
    for(QUrl url : listUrl)
    {
        QString path = url.path();

        // 不要 file:// 前缀只要绝对路径
        if(path.startsWith("file:"))
            path.remove(0, 7);

        // 拖入文件需要做类型判断
        QFileInfo fi(path);
        if (fi.isDir()) {
            // 如果是文件夹的话添加文件夹
            g_user_signal->addDir(path);
        }
        else if (rx_video.indexIn(fi.suffix()) > -1 || rx_audio.indexIn(fi.suffix()) > -1) {
            filelist << path;
        }
    }
    if(filelist.count() == 0)
        return;
    g_user_signal->addFiles(filelist);
}
