void PlayerComponent::handleMpvEvent(mpv_event *event)
{
  switch (event->event_id)
  {
    case MPV_EVENT_START_FILE:
    {
      m_CurrentUrl = mpv::qt::get_property_variant(m_mpv, "path").toString();
      m_playbackStartSent = false;
      break;
    }
    case MPV_EVENT_FILE_LOADED:
    {
      emit playing(m_CurrentUrl);
      break;
    }
    case MPV_EVENT_END_FILE:
    {
      mpv_event_end_file *end_file = (mpv_event_end_file *)event->data;
      switch (end_file->reason)
      {
        case MPV_END_FILE_REASON_EOF:
          emit finished(m_CurrentUrl);
          break;
        case MPV_END_FILE_REASON_ERROR:
          emit error(end_file->error, mpv_error_string(end_file->error));
          break;
        default:
          emit stopped(m_CurrentUrl);
          break;
      }

      emit playbackEnded(m_CurrentUrl);
      m_CurrentUrl = "";

      m_restoreDisplayTimer.start(0);
      break;
    }
    case MPV_EVENT_IDLE:
    {
      emit playbackAllDone();
      break;
    }
    case MPV_EVENT_PLAYBACK_RESTART:
    {
      // it's also sent after seeks are completed
      if (!m_playbackStartSent)
        emit playbackStarting();
      m_playbackStartSent = true;
      break;
    }
    case MPV_EVENT_PROPERTY_CHANGE:
    {
      mpv_event_property *prop = (mpv_event_property *)event->data;
      if (strcmp(prop->name, "pause") == 0 && prop->format == MPV_FORMAT_FLAG)
      {
        int state = *(int *)prop->data;
        emit paused(state);
      }
      else if (strcmp(prop->name, "cache-buffering-state") == 0 && prop->format == MPV_FORMAT_INT64)
      {
        int64_t percentage = *(int64_t *)prop->data;
        emit buffering(percentage);
      }
      else if (strcmp(prop->name, "playback-time") == 0 && prop->format == MPV_FORMAT_DOUBLE)
      {
        double pos = *(double*)prop->data;
        if (fabs(pos - m_lastPositionUpdate) > 0.25)
        {
          quint64 ms = (quint64)(qMax(pos * 1000.0, 0.0));
          emit positionUpdate(ms);
          m_lastPositionUpdate = pos;
        }
      }
      else if (strcmp(prop->name, "vo-configured") == 0)
      {
        int state = prop->format == MPV_FORMAT_FLAG ? *(int *)prop->data : 0;
        emit windowVisible(state);
      }
      else if (strcmp(prop->name, "duration") == 0)
      {
        if (prop->format == MPV_FORMAT_DOUBLE)
          emit updateDuration(*(double *)prop->data * 1000.0);
      }
      else if (strcmp(prop->name, "audio-device-list") == 0)
      {
        updateAudioDeviceList();
      }
      break;
    }
    case MPV_EVENT_LOG_MESSAGE:
    {
      mpv_event_log_message *msg = (mpv_event_log_message *)event->data;
      // Strip the trailing '\n'
      size_t len = strlen(msg->text);
      if (len > 0 && msg->text[len - 1] == '\n')
        len -= 1;
      QString logline = QString::fromUtf8(msg->prefix) + ": " + QString::fromUtf8(msg->text, len);
      if (msg->log_level >= MPV_LOG_LEVEL_V)
        QLOG_DEBUG() << qPrintable(logline);
      else if (msg->log_level >= MPV_LOG_LEVEL_INFO)
        QLOG_INFO() << qPrintable(logline);
      else if (msg->log_level >= MPV_LOG_LEVEL_WARN)
        QLOG_WARN() << qPrintable(logline);
      else
        QLOG_ERROR() << qPrintable(logline);
      break;
    }
    case MPV_EVENT_CLIENT_MESSAGE:
    {
      mpv_event_client_message *msg = (mpv_event_client_message *)event->data;
      // This happens when the player is about to load the file, but no actual loading has taken part yet.
      // We use this to block loading until we explicitly tell it to continue.
      if (msg->num_args >= 3 && !strcmp(msg->args[0], "hook_run") && !strcmp(msg->args[1], "1"))
      {
        QString resume_id = QString::fromUtf8(msg->args[2]);
        // Calling this lambda will instruct mpv to continue loading the file.
        auto resume = [=] {
          QLOG_INFO() << "resuming loading";
          mpv::qt::command_variant(m_mpv, QStringList() << "hook-ack" << resume_id);
        };
        if (switchDisplayFrameRate())
        {
          // Now wait for some time for mode change - this is needed because mode changing can take some
          // time, during which the screen is black, and initializing hardware decoding could fail due
          // to various strange OS-related reasons.
          // (Better hope the user doesn't try to exit Konvergo during mode change.)
          int pause = SettingsComponent::Get().value(SETTINGS_SECTION_VIDEO, "refreshrate.delay").toInt() * 1000;
          QLOG_INFO() << "waiting" << pause << "msec after rate switch before loading";
          QTimer::singleShot(pause, resume);
        }
        else
        {
          resume();
        }
        break;
      }
    }
    default:; /* ignore */
  }
}
void DesktopSelectionWindow::hideEvent(QHideEvent * hideEvt)
{
    QWidget::hideEvent(hideEvt);

    emit windowVisible(false);
}