Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (9)
Showing
with 795 additions and 207 deletions
......@@ -296,6 +296,7 @@ libqt_plugin_la_SOURCES = \
util/covergenerator.hpp \
util/imageluminanceextractor.cpp util/imageluminanceextractor.hpp \
util/csdbuttonmodel.cpp util/csdbuttonmodel.hpp \
util/csdmenu.cpp util/csdmenu.hpp \
util/imagehelper.cpp util/imagehelper.hpp \
util/keyhelper.cpp util/keyhelper.hpp \
util/listcache.hxx util/listcache.hpp \
......@@ -470,6 +471,7 @@ nodist_libqt_plugin_la_SOURCES = \
util/vlcaccess_image_provider.moc.cpp \
util/imageluminanceextractor.moc.cpp \
util/csdbuttonmodel.moc.cpp \
util/csdmenu.moc.cpp \
util/keyhelper.moc.cpp \
util/listcache.moc.cpp \
util/locallistcacheloader.moc.cpp \
......@@ -531,7 +533,9 @@ libqt_plugin_la_SOURCES += \
maininterface/compositor_win7.hpp \
style/windowsthemeprovider.cpp \
maininterface/win32windoweffects_module.cpp \
maininterface/win32windoweffects_module.hpp
maininterface/win32windoweffects_module.hpp \
util/csdmenu_win32.c \
util/csdmenu_win32.h
nodist_libqt_plugin_la_SOURCES += maininterface/mainctx_win32.moc.cpp \
maininterface/compositor_win7.moc.cpp
......@@ -559,7 +563,7 @@ if HAVE_XCB_DAMAGE
if HAVE_XCB_XFIXES
libqt_plugin_la_CXXFLAGS += -DQT_HAS_X11_COMPOSITOR \
$(QT_X11_CFLAGS) $(XCB_RENDER_CFLAGS) $(XCB_COMPOSITE_CFLAGS) $(XLCB_DAMAGE_CFLAGS) $(XCB_XFIXES_CFLAGS)
$(QT_X11_CFLAGS) $(XCB_RENDER_CFLAGS) $(XCB_COMPOSITE_CFLAGS) $(XCB_DAMAGE_CFLAGS) $(XCB_XFIXES_CFLAGS)
libqt_plugin_la_LIBADD += $(QT_X11_LIBS) $(XCB_RENDER_LIBS) $(XCB_COMPOSITE_LIBS) $(XCB_DAMAGE_LIBS) $(XCB_XFIXES_LIBS)
......@@ -579,8 +583,24 @@ nodist_libqt_plugin_la_SOURCES += \
maininterface/compositor_x11.moc.cpp \
maininterface/compositor_x11_renderclient.moc.cpp \
maininterface/compositor_x11_renderwindow.moc.cpp \
maininterface/compositor_x11_uisurface.moc.cpp \
maininterface/compositor_x11_utils.moc.cpp
maininterface/compositor_x11_uisurface.moc.cpp
#extra X11 features
libqt_x11_plugin_la_CXXFLAGS = $(AM_CXXFLAGS) $(XCB_CFLAGS) $(XCB_RENDER_CFLAGS) $(XCB_COMPOSITE_CFLAGS) $(XCB_DAMAGE_CFLAGS) $(XCB_XFIXES_CFLAGS)
libqt_x11_plugin_la_LIBADD = $(XCB_LIBS) $(XCB_RENDER_LIBS) $(XCB_COMPOSITE_LIBS) $(XCB_DAMAGE_LIBS) $(XCB_XFIXES_LIBS)
libqt_x11_plugin_la_SOURCES = \
maininterface/qt_x11_plugin.c \
maininterface/compositor_x11_utils.hpp \
maininterface/compositor_x11_utils.cpp \
util/csdmenu_module.h \
util/csdmenu_x11.cpp \
util/csdmenu_x11.h
if ENABLE_QT
gui_LTLIBRARIES += libqt_x11_plugin.la
endif
endif
endif
......@@ -605,6 +625,7 @@ nodist_libqt_plugin_la_SOURCES += \
libqt_wayland_plugin_la_CFLAGS = $(AM_CFLAGS) $(WAYLAND_CLIENT_CFLAGS)
libqt_wayland_plugin_la_LIBADD = $(WAYLAND_CLIENT_LIBS)
libqt_wayland_plugin_la_SOURCES = \
maininterface/qt_wayland_plugin.c \
maininterface/compositor_wayland_module.c \
maininterface/compositor_wayland_module.h
......@@ -612,9 +633,16 @@ libqt_wayland_plugin_la_SOURCES = \
#if WAYLAND_SCANNER
libqt_wayland_plugin_la_CFLAGS += -DQT_HAS_WAYLAND_PROTOCOLS -I$(builddir)/maininterface
libqt_wayland_plugin_la_SOURCES += \
util/csdmenu_wayland.c \
util/csdmenu_wayland.h \
util/csdmenu_module.h
nodist_libqt_wayland_plugin_la_SOURCES = \
maininterface/viewporter-client-protocol.h \
maininterface/viewporter-protocol.c
maininterface/viewporter-protocol.c \
maininterface/xdg-shell-client-protocol.h \
maininterface/xdg-shell-protocol.c
BUILT_SOURCES += $(nodist_libqt_wayland_plugin_la_SOURCES)
......@@ -627,6 +655,12 @@ maininterface/viewporter-protocol.c: \
maininterface/viewporter-client-protocol.h
$(AM_V_GEN)$(WAYLAND_SCANNER) private-code $< $@
maininterface/xdg-shell-client-protocol.h: $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml Makefile.am
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header $< $@
maininterface/xdg-shell-protocol.c: $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml Makefile.am
$(AM_V_GEN)$(WAYLAND_SCANNER) private-code $< $@
#endif
#endif
......
......@@ -286,7 +286,7 @@ error:
return false;
}
static int Open(vlc_object_t* p_this)
int OpenCompositor(vlc_object_t* p_this)
{
qtwayland_t* obj = (qtwayland_t*)p_this;
......@@ -323,10 +323,3 @@ static int Open(vlc_object_t* p_this)
return VLC_SUCCESS;
}
vlc_module_begin()
set_shortname(N_("QtWayland"))
set_description(N_(" calls for compositing with Qt"))
set_capability("qtwayland", 10)
set_callback(Open)
vlc_module_end()
......@@ -43,5 +43,6 @@ typedef struct qtwayland_t
void (*close)(struct qtwayland_t*);
} qtwayland_t;
int OpenCompositor(vlc_object_t* p_this);
#endif // COMPOSITOR_WAYLAND_MODULE_H
......@@ -258,3 +258,36 @@ QQuickItem * CompositorX11::activeFocusItem() const /* override */
{
return m_qmlView->activeFocusItem();
}
///////// DummyNativeWidget
DummyNativeWidget::DummyNativeWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
setAttribute(Qt::WA_NativeWindow, true);
setAttribute(Qt::WA_OpaquePaintEvent, true);
setAttribute(Qt::WA_PaintOnScreen, true);
setAttribute(Qt::WA_MouseTracking, true);
setAttribute(Qt::WA_TranslucentBackground, false);
QWindow* w = window()->windowHandle();
assert(w);
/*
* force the window not to have an alpha channel, the parent window
* may have an alpha channel and child widget would inhertit the format
* even if we set Qt::WA_TranslucentBackground to false. having an alpha
* in this surface would lead to the video begin semi-tranparent.
*/
QSurfaceFormat format = w->format();
format.setAlphaBufferSize(0);
w->setFormat(format);
}
DummyNativeWidget::~DummyNativeWidget()
{
}
QPaintEngine* DummyNativeWidget::paintEngine() const
{
return nullptr;
}
......@@ -22,6 +22,8 @@
#include "videosurface.hpp"
#include <memory>
#include <QWidget>
#include <xcb/xcb.h>
class QObject;
......@@ -68,6 +70,18 @@ private:
std::unique_ptr<CompositorX11RenderWindow> m_renderWindow;
};
class DummyNativeWidget : public QWidget
{
Q_OBJECT
public:
DummyNativeWidget(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
virtual ~DummyNativeWidget();
//override paintEnging to suppress warning
QPaintEngine* paintEngine() const override;
};
}
#endif // COMPOSITORX11_HPP
......@@ -15,44 +15,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <xcb/xfixes.h>
#include <vlc_cxx_helpers.hpp>
#include "compositor_x11_utils.hpp"
#include <QWindow>
#include <vector>
#include <algorithm>
#include <cstring>
namespace vlc {
DummyNativeWidget::DummyNativeWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
setAttribute(Qt::WA_NativeWindow, true);
setAttribute(Qt::WA_OpaquePaintEvent, true);
setAttribute(Qt::WA_PaintOnScreen, true);
setAttribute(Qt::WA_MouseTracking, true);
setAttribute(Qt::WA_TranslucentBackground, false);
QWindow* w = window()->windowHandle();
assert(w);
/*
* force the window not to have an alpha channel, the parent window
* may have an alpha channel and child widget would inhertit the format
* even if we set Qt::WA_TranslucentBackground to false. having an alpha
* in this surface would lead to the video begin semi-tranparent.
*/
QSurfaceFormat format = w->format();
format.setAlphaBufferSize(0);
w->setFormat(format);
}
#include <vlc_cxx_helpers.hpp>
DummyNativeWidget::~DummyNativeWidget()
{
#include <xcb/xfixes.h>
}
#include "compositor_x11_utils.hpp"
QPaintEngine* DummyNativeWidget::paintEngine() const
{
return nullptr;
}
namespace vlc {
bool queryExtension(xcb_connection_t* conn, const char* name, uint8_t* first_event_out, uint8_t* first_error_out)
{
......@@ -133,10 +106,10 @@ void setTransparentForMouseEvent(xcb_connection_t* conn, xcb_window_t window)
//see https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm45894597940912
bool wmScreenHasCompositor(xcb_connection_t* conn, int screen)
{
QByteArray propName("_NET_WM_CM_S");
propName += QByteArray::number(screen);
std::string propName("_NET_WM_CM_S");
propName += std::to_string(screen);
xcb_atom_t atom = getInternAtom(conn, propName.constData());
xcb_atom_t atom = getInternAtom(conn, propName.c_str());
if (atom == 0)
return false;
......
......@@ -19,26 +19,12 @@
#define COMPOSITOR_X11_UTILS_HPP
#include <memory>
#include <QWidget>
#include <xcb/xcb.h>
#include <xcb/render.h>
#include <xcb/composite.h>
namespace vlc {
class DummyNativeWidget : public QWidget
{
Q_OBJECT
public:
DummyNativeWidget(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
virtual ~DummyNativeWidget();
//override paintEnging to suppress warning
QPaintEngine* paintEngine() const override;
};
template<typename T, typename R, R RELEASE>
class X11Resource {
public:
......
......@@ -117,103 +117,6 @@ HWND WinId( QWindow *windowHandle )
return 0;
}
bool isWindowFixedSize(const QWindow *window)
{
if (window->flags() & Qt::MSWindowsFixedSizeDialogHint)
return true;
const auto minSize = window->minimumSize();
const auto maxSize = window->maximumSize();
return minSize.isValid() && maxSize.isValid() && minSize == maxSize;
}
class WinSystemMenuButton : public SystemMenuButton
{
public:
WinSystemMenuButton(QWindow *window, QObject *parent)
: SystemMenuButton {parent}
, m_window {window}
{
connect(this, &CSDButton::clicked, this, &WinSystemMenuButton::handleClick);
connect(this, &CSDButton::doubleClicked, this, &WinSystemMenuButton::handleDoubleClick);
}
void showSystemMenu(const QPoint &windowpos) override
{
HWND hwnd = (HWND)m_window->winId();
HMENU hmenu = ::GetSystemMenu(hwnd, FALSE);
if (!hmenu)
return;
// Tweak the menu items according to the current window status.
const auto winState = m_window->windowStates();
const bool maxOrFull = (winState.testFlag(Qt::WindowMaximized) || winState.testFlag(Qt::WindowFullScreen));
const bool fixedSize = isWindowFixedSize(m_window);
EnableMenuItem(hmenu, SC_MOVE, (MF_BYCOMMAND | (!maxOrFull ? MFS_ENABLED : MFS_DISABLED)));
EnableMenuItem(hmenu, SC_SIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
EnableMenuItem(hmenu, SC_RESTORE, (MF_BYCOMMAND | ((maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
EnableMenuItem(hmenu, SC_MINIMIZE, (MF_BYCOMMAND | MFS_ENABLED));
EnableMenuItem(hmenu, SC_MAXIMIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
EnableMenuItem(hmenu, SC_CLOSE, (MF_BYCOMMAND | MFS_ENABLED));
// map pos to screen points and convert according to device DPR, required on HI-DPI displays
const auto screenPoints = m_window->mapToGlobal(windowpos) * m_window->devicePixelRatio();
const auto alignment = (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN);
// show menu
emit systemMenuVisibilityChanged(true);
const int action = TrackPopupMenu(hmenu, (TPM_RETURNCMD | alignment)
, screenPoints.x(), screenPoints.y()
, 0, hwnd, nullptr);
// unlike native system menu which sends WM_SYSCOMMAND, TrackPopupMenu sends WM_COMMAND
// imitate native system menu by sending the action manually as WM_SYSCOMMAND
PostMessageW(hwnd, WM_SYSCOMMAND, action, 0);
emit systemMenuVisibilityChanged(false);
}
private:
// target window
QWindow *m_window = {};
// used to reject click() incase a doubleClick() is followed
bool m_triggerSystemMenu = false;
void handleClick()
{
// delay the show of sytem menu to check if this 'click' is
// a double click, 'm_triggerSystemMenu' is used to reject the
// queued 'showSystemMenu' call in case this is a double click
m_triggerSystemMenu = true;
QTimer::singleShot(100, this, [this]()
{
if (!m_triggerSystemMenu)
return;
// show system menu 'margin' below the rect
constexpr QPoint margin {0, 4};
showSystemMenu(rect().bottomLeft() + margin);
});
}
void handleDoubleClick()
{
// reject any queued showSystemMenu call
m_triggerSystemMenu = false;
m_window->close();
}
};
class CSDWin32EventHandler : public QObject, public QAbstractNativeEventFilter
{
public:
......@@ -827,9 +730,6 @@ InterfaceWindowHandlerWin32::InterfaceWindowHandlerWin32(qt_intf_t *_p_intf, Mai
m_disableVolumeKeys = disable;
});
auto systemMenuButton = std::make_shared<WinSystemMenuButton>(mainCtx->intfMainWindow(), nullptr);
mainCtx->csdButtonModel()->setSystemMenuButton(systemMenuButton);
QApplication::instance()->installNativeEventFilter(this);
}
......
......@@ -33,6 +33,7 @@
#include "playlist/playlist_model.hpp"
#include "playlist/playlist_controller.hpp"
#include "util/csdmenu.hpp"
#include "util/item_key_event_filter.hpp"
#include "util/imageluminanceextractor.hpp"
#include "util/keyhelper.hpp"
......@@ -182,8 +183,8 @@ void MainUI::registerQMLTypes()
qmlRegisterUncreatableType<VLCVarChoiceModel>(uri, versionMajor, versionMinor, "VLCVarChoiceModel", "generic variable with choice model" );
qmlRegisterUncreatableType<CSDButton>(uri, versionMajor, versionMinor, "CSDButton", "");
qmlRegisterUncreatableType<CSDButtonModel>(uri, versionMajor, versionMinor, "CSDButtonModel", "has CSD buttons and provides for communicating CSD events between UI and backend");
qmlRegisterTypesAndRevisions<CSDMenu>( uri, versionMajor);
qmlRegisterUncreatableType<NavigationAttached>( uri, versionMajor, versionMinor, "Navigation", "Navigation is only available via attached properties");
qmlRegisterModule(uri, versionMajor, versionMinor);
qmlProtectModule(uri, versionMajor);
}
......
/*****************************************************************************
* Copyright (C) 2024 VLC authors and VideoLAN
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "compositor_wayland_module.h"
#ifdef QT_HAS_WAYLAND_PROTOCOLS
#include "util/csdmenu_wayland.h"
#endif
vlc_module_begin()
set_shortname(N_("QtWayland"))
set_description(N_(" calls for compositing with Qt"))
set_capability("qtwayland", 10)
set_callback(OpenCompositor)
#ifdef QT_HAS_WAYLAND_PROTOCOLS
add_submodule()
set_capability("qtcsdmenu", 10)
set_callbacks(WaylandCSDMenuOpen, WaylandCSDMenuClose)
#endif
vlc_module_end()
/*****************************************************************************
* Copyright (C) 2024 VLC authors and VideoLAN
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "util/csdmenu_x11.h"
vlc_module_begin()
set_shortname(N_("QtX11"))
set_description(N_("Qt extra X11 features"))
set_capability("qtcsdmenu", 10)
set_callback(X11CSDMenuOpen)
vlc_module_end()
......@@ -128,6 +128,7 @@ moc_headers = files(
'util/color_svg_image_provider.hpp',
'util/vlcaccess_image_provider.hpp',
'util/csdbuttonmodel.hpp',
'util/csdmenu.hpp',
'util/imageluminanceextractor.hpp',
'util/keyhelper.hpp',
'util/listcache.hpp',
......@@ -431,6 +432,8 @@ some_sources = files(
'util/covergenerator.hpp',
'util/csdbuttonmodel.cpp',
'util/csdbuttonmodel.hpp',
'util/csdmenu.cpp',
'util/csdmenu.hpp',
'util/imageluminanceextractor.cpp',
'util/imageluminanceextractor.hpp',
'util/imagehelper.cpp',
......@@ -507,6 +510,8 @@ if host_system == 'windows'
'maininterface/compositor_win7.cpp',
'maininterface/compositor_win7.hpp',
'style/windowsthemeprovider.cpp',
'util/csdmenu_win32.c',
'util/csdmenu_win32.h',
)
if cdata.has('HAVE_DCOMP_H')
......@@ -1056,6 +1061,23 @@ if qt6_dep.found()
endif
endif
if (xcb_dep.found() and xcb_render_dep.found() and xcb_xfixes_dep.found())
vlc_modules += {
'name' : 'qt_x11',
'include_directories' : qt_include_dir,
'sources' : files(
'maininterface/qt_x11_plugin.c',
'maininterface/compositor_x11_utils.hpp',
'maininterface/compositor_x11_utils.cpp',
'util/csdmenu_module.h',
'util/csdmenu_x11.cpp',
'util/csdmenu_x11.h'
),
'dependencies' : [xcb_dep, xcb_render_dep, xcb_xfixes_dep]
}
endif
# TODO support qmlcachegen
vlc_modules += {
......
......@@ -198,6 +198,14 @@ FocusScope{
anchors.fill: parent
active: root.showCSD
source: "qrc:///qt/qml/VLC/Widgets/CSDTitlebarTapNDrapHandler.qml"
Connections {
target: tapNDrag.item
enabled: tapNDrag.status === Loader.Ready
function onCsdMenuVisibleChanged() {
root.requestLockUnlockAutoHide(tapNDrag.item.csdMenuVisible)
}
}
}
// Components -
......@@ -276,13 +284,7 @@ FocusScope{
color: theme.accent
Connections {
target: logo.button
function onSystemMenuVisibilityChanged() {
root.requestLockUnlockAutoHide(visible)
}
}
onCsdMenuVisibleChanged: root.requestLockUnlockAutoHide(csdMenuVisible)
}
}
......
......@@ -72,6 +72,7 @@ extern "C" char **environ;
#ifdef _WIN32
# include "maininterface/mainctx_win32.hpp"
#include "maininterface/win32windoweffects_module.hpp"
#include "util/csdmenu_win32.h"
#else
# include "maininterface/mainctx.hpp" /* MainCtx creation */
#endif
......@@ -469,6 +470,11 @@ vlc_module_begin ()
set_description( "Provides window effects on Windows." )
set_capability( "qtwindoweffects", 10 )
set_callback( QtWin32WindowEffectsOpen )
add_submodule ()
add_shortcut( "QtWin32CSDMenu" )
set_description( "Provides csd menu on Windows." )
set_capability( "qtcsdmenu", 10 )
set_callback( QtWin32CSDMenuOpen )
#endif
add_submodule()
set_capability("qt theme provider", 1)
......
......@@ -127,16 +127,6 @@ QList<CSDButton *> CSDButtonModel::windowCSDButtons() const
return m_windowCSDButtons;
}
CSDButton *CSDButtonModel::systemMenuButton() const
{
return m_systemMenuButton.get();
}
void CSDButtonModel::setSystemMenuButton(std::shared_ptr<SystemMenuButton> button)
{
m_systemMenuButton = std::move(button);
}
void CSDButtonModel::minimizeButtonClicked()
{
......
......@@ -90,21 +90,6 @@ private:
bool m_externalPressed = false;
};
class SystemMenuButton : public CSDButton
{
Q_OBJECT
public:
SystemMenuButton(QObject *parent = nullptr) : CSDButton {SystemMenuButton::SystemMenu, parent} {}
Q_INVOKABLE virtual void showSystemMenu(const QPoint &windowpos) = 0;
signals:
void systemMenuVisibilityChanged(bool visible);
};
class MainCtx;
......@@ -113,17 +98,10 @@ class CSDButtonModel : public QObject
Q_OBJECT
Q_PROPERTY(QList<CSDButton *> windowCSDButtons READ windowCSDButtons CONSTANT)
Q_PROPERTY(CSDButton *systemMenuButton READ systemMenuButton CONSTANT)
public:
CSDButtonModel(MainCtx *mainCtx, QObject *parent = nullptr);
QList<CSDButton *> windowCSDButtons() const;
CSDButton *systemMenuButton() const;
// set by internal implmentation
// all the actions are also handled by implementation
void setSystemMenuButton(std::shared_ptr<SystemMenuButton> button);
private slots:
void minimizeButtonClicked();
......@@ -135,9 +113,6 @@ private:
// CSD window action buttons i.e minimize, maximize, close
QList<CSDButton *> m_windowCSDButtons;
// sysmenu button, available on windows only
std::shared_ptr<SystemMenuButton> m_systemMenuButton = nullptr;
};
......
/*****************************************************************************
* Copyright (C) 2024 VLC authors and VideoLAN
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "csdmenu.hpp"
#include <QApplication>
#include <QAction>
#include <QWindow>
#ifdef QT_GUI_PRIVATE
#include <QtGui/qpa/qplatformnativeinterface.h>
#include <QtGui/qpa/qplatformwindow.h>
#include <QtGui/qpa/qplatformwindow_p.h>
#endif
#include "maininterface/mainctx.hpp"
#include "util/csdmenu_module.h"
#include "menus/menus.hpp"
#include <vlc_common.h>
#include <vlc_modules.h>
struct xdg_surface;
namespace {
//vlc module callback
static int csdMenuInfoOpen(void *func, bool forced, va_list ap)
{
VLC_UNUSED(forced);
qt_csd_menu_open open = reinterpret_cast<qt_csd_menu_open>(func);
qt_csd_menu_t* obj = va_arg(ap, qt_csd_menu_t*);
qt_csd_menu_info* info = va_arg(ap, qt_csd_menu_info*);
return open(obj, info);
}
bool isWindowFixedSize(const QWindow *window)
{
if (window->flags() & Qt::MSWindowsFixedSizeDialogHint)
return true;
const auto minSize = window->minimumSize();
const auto maxSize = window->maximumSize();
return minSize.isValid() && maxSize.isValid() && minSize == maxSize;
}
}
class CSDMenuPrivate
{
Q_DECLARE_PUBLIC(CSDMenu)
public:
CSDMenuPrivate(CSDMenu* parent)
: q_ptr(parent)
{
const QString& platform = qApp->platformName();;
if (platform == QLatin1String("windows") || platform == QLatin1String("direct2d"))
m_plateform = QT_CSD_PLATFORM_WINDOWS;
else if (platform.startsWith( QLatin1String("wayland")))
m_plateform = QT_CSD_PLATFORM_WAYLAND;
else if (platform == QLatin1String("xcb"))
m_plateform = QT_CSD_PLATFORM_X11;
}
static void notifyMenuVisible(void* data, bool visible)
{
auto that = static_cast<CSDMenuPrivate*>(data);
that->m_menuVisible = visible;
emit that->q_func()->menuVisibleChanged(visible);
}
void fallbackMenu(QPoint pos)
{
auto menu = new VLCMenu(m_ctx->getIntf());
menu->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(menu, &QMenu::aboutToShow, q_ptr, [this](){
notifyMenuVisible(this, true);
});
QObject::connect(menu, &QMenu::aboutToHide, q_ptr, [this](){
notifyMenuVisible(this, false);
});
QWindow::Visibility visibility = m_ctx->interfaceVisibility();
QAction* action;
action = menu->addAction(qtr("Restore"));
action->setEnabled(visibility != QWindow::Windowed);
action->connect(action, &QAction::triggered, q_ptr, [this]() {
m_ctx->requestInterfaceNormal();
});
action = menu->addAction(qtr("Minimize"));
action->connect(action, &QAction::triggered, q_ptr, [this]() {
m_ctx->requestInterfaceMinimized();
});
action = menu->addAction(qtr("Maximized"));
action->setEnabled(visibility != QWindow::Maximized);
action->connect(action, &QAction::triggered, q_ptr, [this]() {
m_ctx->requestInterfaceMaximized();
});
action = menu->addAction(qtr("Always on top"));
action->setCheckable(true);
action->setChecked(m_ctx->isInterfaceAlwaysOnTop());
action->connect(action, &QAction::triggered, q_ptr, [this](bool checked) {
m_ctx->setInterfaceAlwaysOnTop(checked);
});
action = menu->addAction(qtr("Close"));
action->connect(action, &QAction::triggered, q_ptr, [this]() {
m_ctx->intfMainWindow()->close();
});
/* Ideally we should allow moving and resizing the window through startSystemXXX
* But, startSystemXXX is usually active from a mouse press until a mouse release,
* so calling it from a menu is broken with some desktop environments
*/
menu->popup(pos);
}
void loadModule()
{
QWindow* window = m_ctx->intfMainWindow();
assert(window);
qt_csd_menu_info info = {};
info.platform = QT_CSD_PLATFORM_UNKNOWN;
#ifdef _WIN32
if (m_plateform == QT_CSD_PLATFORM_WINDOWS)
{
info.platform = QT_CSD_PLATFORM_WINDOWS;
};
#else
#ifdef QT_GUI_PRIVATE
if (m_plateform == QT_CSD_PLATFORM_X11)
{
QPlatformNativeInterface* native = qApp->platformNativeInterface();
info.platform = QT_CSD_PLATFORM_X11;
info.data.x11.rootwindow = reinterpret_cast<intptr_t>(native->nativeResourceForIntegration(QByteArrayLiteral("rootwindow")));
info.data.x11.connection = reinterpret_cast<struct xcb_connection_t*>(native->nativeResourceForIntegration(QByteArrayLiteral("connection")));
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
if (m_plateform == QT_CSD_PLATFORM_WAYLAND)
{
info.platform = QT_CSD_PLATFORM_WAYLAND;
auto appNative = qApp->nativeInterface<QNativeInterface::QWaylandApplication>();
auto windowNative = window->nativeInterface<QNativeInterface::Private::QWaylandWindow>();
info.data.wayland.display = appNative->display();
info.data.wayland.toplevel = windowNative->surfaceRole<xdg_toplevel>();
}
#endif // QT 6.5
#endif // QT_GUI_PRIVATE
#endif // _WIN32
info.isRtl = QGuiApplication::isRightToLeft();
info.userData = this;
info.notifyMenuVisible = &notifyMenuVisible;
m_systemMenuState = UNAVAILABLE;
m_systemMenu = vlc_object_create<qt_csd_menu_t>(m_ctx->getIntf());
if (!m_systemMenu)
return;
m_module = vlc_module_load(vlc_object_logger(m_systemMenu), "qtcsdmenu", nullptr, false, &csdMenuInfoOpen, m_systemMenu, &info);
if (!m_module)
{
vlc_object_delete(m_systemMenu);
m_systemMenu = nullptr;
return;
}
m_systemMenuState = AVAILABLE;
}
void unloadModule()
{
if (m_module)
{
module_unneed(m_systemMenu, m_module);
m_module = nullptr;
}
if (m_systemMenu)
{
vlc_object_delete(m_systemMenu);
m_systemMenu = nullptr;
}
m_systemMenuState = CSDMenuPrivate::NEED_INITIALISATION;
}
enum {
NEED_INITIALISATION,
UNAVAILABLE,
AVAILABLE
} m_systemMenuState = NEED_INITIALISATION;
module_t* m_module = nullptr;
qt_csd_menu_t* m_systemMenu = nullptr;
qt_csd_menu_platform m_plateform = QT_CSD_PLATFORM_UNKNOWN;
MainCtx* m_ctx = nullptr;
bool m_menuVisible = false;
CSDMenu* q_ptr;
};
CSDMenu::CSDMenu(QObject* parent)
: QObject(parent)
, d_ptr(new CSDMenuPrivate(this))
{
}
CSDMenu::~CSDMenu()
{
Q_D(CSDMenu);
d->unloadModule();
}
MainCtx* CSDMenu::getCtx() const
{
Q_D(const CSDMenu);
return d->m_ctx;
}
void CSDMenu::setCtx(MainCtx* ctx)
{
Q_D(CSDMenu);
if (d->m_ctx == ctx)
return;
d->m_ctx = ctx;
emit ctxChanged(ctx);
}
bool CSDMenu::getMenuVisible() const
{
Q_D(const CSDMenu);
return d->m_menuVisible;
}
void CSDMenu::popup(const QPoint &pos)
{
Q_D(CSDMenu);
assert(d->m_ctx);
QWindow* window = d->m_ctx->intfMainWindow();
assert(window);
if (d->m_systemMenuState == CSDMenuPrivate::NEED_INITIALISATION)
d->loadModule();
if (d->m_systemMenuState == CSDMenuPrivate::AVAILABLE) {
assert(d->m_systemMenu);
qreal qtDpr = window->devicePixelRatio();
QPlatformWindow* nativeWindow = window->handle();
qreal nativeDpr = nativeWindow->devicePixelRatio();
qt_csd_menu_event event = {};
event.platform = QT_CSD_PLATFORM_UNKNOWN;
event.x = (pos.x() * qtDpr) / nativeDpr;
event.y = (pos.y() * qtDpr) / nativeDpr;
const auto winState = window->windowStates();
int windowFlags = (winState.testFlag(Qt::WindowMaximized) ? QT_CSD_WINDOW_MAXIMIZED : 0)
| (winState.testFlag(Qt::WindowFullScreen) ? QT_CSD_WINDOW_FULLSCREEN : 0)
| (winState.testFlag(Qt::WindowMinimized) ? QT_CSD_WINDOW_MINIMIZED: 0)
| (isWindowFixedSize(window) ? QT_CSD_WINDOW_FIXED_SIZE : 0);
event.windowState = static_cast<qt_csd_menu_window_state>(windowFlags);
#ifdef _WIN32
if (d->m_plateform == QT_CSD_PLATFORM_WINDOWS)
{
event.platform = QT_CSD_PLATFORM_WINDOWS;
event.data.win32.hwnd = reinterpret_cast<void*>(window->winId());
}
#else
#ifdef QT_GUI_PRIVATE
if (d->m_plateform == QT_CSD_PLATFORM_X11)
{
event.platform = QT_CSD_PLATFORM_X11;
event.data.x11.window = window->winId();
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
if (d->m_plateform == QT_CSD_PLATFORM_WAYLAND)
{
event.platform = QT_CSD_PLATFORM_WAYLAND;
auto appNative = qApp->nativeInterface<QNativeInterface::QWaylandApplication>();
assert(appNative);
event.data.wayland.seat = appNative->lastInputSeat();
event.data.wayland.serial = appNative->lastInputSerial();
}
#endif // Qt 6.5
#endif // QT_GUI_PRIVATE
#endif // _WIN32
bool ret = d->m_systemMenu->popup(d->m_systemMenu, &event);
if (ret)
return;
}
d->fallbackMenu(pos);
}
/*****************************************************************************
* Copyright (C) 2024 VLC authors and VideoLAN
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef CSDMENU_HPP
#define CSDMENU_HPP
#include <QQmlEngine>
#include <QMenu>
Q_MOC_INCLUDE("maininterface/mainctx.hpp")
class MainCtx;
class CSDMenuPrivate;
class CSDMenu : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(MainCtx* ctx READ getCtx WRITE setCtx NOTIFY ctxChanged FINAL)
Q_PROPERTY(bool menuVisible READ getMenuVisible NOTIFY menuVisibleChanged FINAL)
public:
explicit CSDMenu(QObject* parent = nullptr);
~CSDMenu();
public:
Q_INVOKABLE void popup(const QPoint &windowpos);
MainCtx* getCtx() const;
void setCtx(MainCtx* ctx);
bool getMenuVisible() const;
signals:
void ctxChanged(MainCtx*);
void menuVisibleChanged(bool);
protected:
QScopedPointer<CSDMenuPrivate> d_ptr;
Q_DECLARE_PRIVATE(CSDMenu)
};
#endif // CSDMENU_HPP
#ifndef QTCSDMENU_MODULE_H
#define QTCSDMENU_MODULE_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_objects.h>
#include <stdint.h>
struct xcb_connection_t;
struct wl_display;
struct wl_seat;
struct xdg_toplevel;
typedef enum {
QT_CSD_PLATFORM_UNKNOWN,
QT_CSD_PLATFORM_WAYLAND,
QT_CSD_PLATFORM_X11,
QT_CSD_PLATFORM_WINDOWS
} qt_csd_menu_platform;
typedef enum {
QT_CSD_WINDOW_FULLSCREEN = (1 << 0),
QT_CSD_WINDOW_MAXIMIZED = (1 << 1),
QT_CSD_WINDOW_MINIMIZED = (1 << 2),
QT_CSD_WINDOW_FIXED_SIZE = (1 << 3)
} qt_csd_menu_window_state;
typedef void (*notifyMenuVisibleCallback)(void* userData, bool visible);
//information about the window, plateform dependent
typedef struct {
qt_csd_menu_platform platform;
union {
struct {
struct xcb_connection_t* connection;
uint32_t rootwindow;
} x11;
struct {
struct wl_display* display;
struct xdg_toplevel* toplevel;
} wayland;
struct {
void* hwnd;
} windows;
} data;
//is the UI rtl or ltr
bool isRtl;
//callback called to notify that the menu is visible/hidden
notifyMenuVisibleCallback notifyMenuVisible;
//user data passed to callbacks
void* userData;
} qt_csd_menu_info;
typedef struct {
qt_csd_menu_platform platform;
union {
struct {
struct wl_seat* seat;
uint32_t serial;
} wayland;
struct {
uint32_t window;
} x11;
struct {
void* hwnd;
} win32;
} data;
int x;
int y;
qt_csd_menu_window_state windowState;
} qt_csd_menu_event;
typedef struct qt_csd_menu_t {
struct vlc_object_t obj;
void* p_sys;
bool (*popup)(struct qt_csd_menu_t* menu, qt_csd_menu_event* event);
} qt_csd_menu_t;
typedef int (*qt_csd_menu_open)(qt_csd_menu_t* obj, qt_csd_menu_info* info);
#endif // QTCSDMENU_MODULE_H
/*****************************************************************************
* Copyright (C) 2024 VLC authors and VideoLAN
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "csdmenu_wayland.h"
#include <assert.h>
#include <wayland-client.h>
#include "xdg-shell-client-protocol.h"
typedef struct {
struct wl_display* display;
struct wl_event_queue* queue;
struct xdg_wm_base *wm_base;
struct xdg_toplevel *toplevel;
bool supportWindowMenu;
} csd_menu_priv_t;
static void csd_registry_global_cb(void* data, struct wl_registry* registry,
uint32_t id, const char* iface, uint32_t version)
{
qt_csd_menu_t* obj = (qt_csd_menu_t*)data;
csd_menu_priv_t* sys = (csd_menu_priv_t*)obj->p_sys;
if (!strcmp(iface, "xdg_wm_base")) {
sys->wm_base = (struct xdg_wm_base*)wl_registry_bind(registry, id, &xdg_wm_base_interface, version);
}
}
static void csd_registry_global_remove_cb(void* data, struct wl_registry* registry, uint32_t id)
{
VLC_UNUSED(data);
VLC_UNUSED(registry);
VLC_UNUSED(id);
}
static const struct wl_registry_listener csd_registry_cbs = {
csd_registry_global_cb,
csd_registry_global_remove_cb,
};
static bool CSDMenuPopup(qt_csd_menu_t* p_this, qt_csd_menu_event* event)
{
csd_menu_priv_t* sys = (csd_menu_priv_t*)p_this->p_sys;
assert (event->platform == QT_CSD_PLATFORM_WAYLAND);
if (!sys->supportWindowMenu)
return false;
xdg_toplevel_show_window_menu(sys->toplevel, event->data.wayland.seat, event->data.wayland.serial, event->x, event->y);
return true;
}
void WaylandCSDMenuClose(vlc_object_t* obj)
{
qt_csd_menu_t* menu = (qt_csd_menu_t*)obj;
csd_menu_priv_t* sys = (csd_menu_priv_t*)menu->p_sys;
if (sys->wm_base)
xdg_wm_base_destroy(sys->wm_base);
if (sys->queue)
wl_event_queue_destroy(sys->queue);
}
int WaylandCSDMenuOpen(qt_csd_menu_t* p_this, qt_csd_menu_info* info)
{
if (info->platform != QT_CSD_PLATFORM_WAYLAND) {
return VLC_EGENERIC;
}
if (info->data.wayland.display == NULL || info->data.wayland.toplevel == NULL) {
msg_Warn(p_this, "wayland display or surface not provided");
return VLC_EGENERIC;
}
csd_menu_priv_t* sys = (csd_menu_priv_t*)vlc_obj_calloc(p_this, 1, sizeof(csd_menu_priv_t));
if (!sys)
return VLC_ENOMEM;
p_this->p_sys = sys;
sys->display = info->data.wayland.display;
sys->queue = wl_display_create_queue(sys->display);
void* wrapper = wl_proxy_create_wrapper(sys->display);
wl_proxy_set_queue((struct wl_proxy*)wrapper, sys->queue);
struct wl_registry* registry = wl_display_get_registry((struct wl_display*)wrapper);
wl_proxy_wrapper_destroy(wrapper);
wl_registry_add_listener(registry, &csd_registry_cbs, p_this);
wl_display_roundtrip_queue(sys->display, sys->queue);
wl_registry_destroy(registry);
if (!sys->wm_base) {
msg_Dbg(p_this, "wm_base not found");
goto error;
}
sys->toplevel = info->data.wayland.toplevel;
//module functions
p_this->popup = CSDMenuPopup;
return VLC_SUCCESS;
error:
p_this->p_sys = NULL;
WaylandCSDMenuClose(VLC_OBJECT(p_this));
vlc_obj_free(p_this, sys);
return VLC_EGENERIC;
}