UI: Use Qt lib for screen info instead of x11 libs

All of the monitor discovery logic can be implemented with Qt. This
change removes all the x11 implementations in favor of Qt and removes a
fair amount of platform specific code.
master
Warren Turkal 2016-10-03 23:50:13 -07:00
parent 580cfc1a95
commit f3eb8aacfe
9 changed files with 33 additions and 156 deletions

View File

@ -83,19 +83,7 @@ elseif(UNIX)
set(obs_PLATFORM_SOURCES
platform-x11.cpp)
find_package(XCB COMPONENTS XCB REQUIRED RANDR REQUIRED XINERAMA REQUIRED)
include_directories(
${XCB_INCLUDE_DIRS}
${X11_XCB_INCLUDE_DIRS})
add_definitions(
${XCB_DEFINITIONS}
${X11_XCB_DEFINITIONS})
set(obs_PLATFORM_LIBRARIES
${XCB_LIBRARIES}
${X11_XCB_LIBRARIES}
set(obs_PLATFORM_LIBRARIES
Qt5::X11Extras)
endif()

View File

@ -29,7 +29,9 @@
#include <obs-config.h>
#include <obs.hpp>
#include <QGuiApplication>
#include <QProxyStyle>
#include <QScreen>
#include "qt-wrappers.hpp"
#include "obs-app.hpp"
@ -1520,20 +1522,10 @@ bool GetClosestUnusedFileName(std::string &path, const char *extension)
bool WindowPositionValid(QRect rect)
{
vector<MonitorInfo> monitors;
GetMonitors(monitors);
for (auto &monitor : monitors) {
int left = int(monitor.x);
int top = int(monitor.y);
int right = left + int(monitor.cx);
int bottom = top + int(monitor.cy);
if ((rect.left() - right) < 0 && (left - rect.right()) < 0 &&
(rect.top() - bottom) < 0 && (top - rect.bottom()) < 0)
for (QScreen* screen: QGuiApplication::screens()) {
if (screen->availableGeometry().intersects(rect))
return true;
}
return false;
}

View File

@ -36,17 +36,6 @@ bool GetDataFilePath(const char *data, string &output)
return !access(output.c_str(), R_OK);
}
void GetMonitors(vector<MonitorInfo> &monitors)
{
monitors.clear();
for(NSScreen *screen : [NSScreen screens])
{
NSRect frame = [screen convertRectToBacking:[screen frame]];
monitors.emplace_back(frame.origin.x, frame.origin.y,
frame.size.width, frame.size.height);
}
}
bool InitApplicationBundle()
{
#ifdef OBS_OSX_BUNDLE

View File

@ -51,28 +51,6 @@ bool GetDataFilePath(const char *data, string &output)
return check_path(data, OBS_DATA_PATH "/obs-studio/", output);
}
static BOOL CALLBACK OBSMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor,
LPRECT rect, LPARAM param)
{
vector<MonitorInfo> &monitors = *(vector<MonitorInfo> *)param;
monitors.emplace_back(
rect->left,
rect->top,
rect->right - rect->left,
rect->bottom - rect->top);
UNUSED_PARAMETER(hMonitor);
UNUSED_PARAMETER(hdcMonitor);
return true;
}
void GetMonitors(vector<MonitorInfo> &monitors)
{
monitors.clear();
EnumDisplayMonitors(NULL, NULL, OBSMonitorEnumProc, (LPARAM)&monitors);
}
bool InitApplicationBundle()
{
return true;

View File

@ -16,16 +16,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/* Here we use xinerama to fetch data about monitor geometry
* Even if there are not multiple monitors, this should still work.
*/
#include <obs-config.h>
#include "obs-app.hpp"
#include <xcb/xcb.h>
#include <xcb/xinerama.h>
#include <xcb/randr.h>
#include <QGuiApplication>
#include <QScreen>
#include <unistd.h>
#include <sstream>
#include <locale.h>
@ -63,59 +59,6 @@ bool GetDataFilePath(const char *data, string &output)
return false;
}
void GetMonitors(vector<MonitorInfo> &monitors)
{
xcb_connection_t* xcb_conn;
monitors.clear();
xcb_conn = xcb_connect(NULL, NULL);
bool use_xinerama = false;
if (xcb_get_extension_data(xcb_conn, &xcb_xinerama_id)->present) {
xcb_xinerama_is_active_cookie_t xinerama_cookie;
xcb_xinerama_is_active_reply_t* xinerama_reply = NULL;
xinerama_cookie = xcb_xinerama_is_active(xcb_conn);
xinerama_reply = xcb_xinerama_is_active_reply(xcb_conn,
xinerama_cookie, NULL);
if (xinerama_reply && xinerama_reply->state != 0)
use_xinerama = true;
free(xinerama_reply);
}
if (use_xinerama) {
xcb_xinerama_query_screens_cookie_t screens_cookie;
xcb_xinerama_query_screens_reply_t* screens_reply = NULL;
xcb_xinerama_screen_info_iterator_t iter;
screens_cookie = xcb_xinerama_query_screens(xcb_conn);
screens_reply = xcb_xinerama_query_screens_reply(xcb_conn,
screens_cookie, NULL);
iter = xcb_xinerama_query_screens_screen_info_iterator(
screens_reply);
for(; iter.rem; xcb_xinerama_screen_info_next(&iter)) {
monitors.emplace_back(iter.data->x_org,
iter.data->y_org,
iter.data->width,
iter.data->height);
}
free(screens_reply);
} else {
// no xinerama so fall back to basic x11 calls
xcb_screen_iterator_t iter;
iter = xcb_setup_roots_iterator(xcb_get_setup(xcb_conn));
for(; iter.rem; xcb_screen_next(&iter)) {
monitors.emplace_back(0,0,iter.data->width_in_pixels,
iter.data->height_in_pixels);
}
}
xcb_disconnect(xcb_conn);
}
bool InitApplicationBundle()
{
return true;

View File

@ -24,19 +24,8 @@
class QWidget;
struct MonitorInfo {
int32_t x, y;
uint32_t cx, cy;
inline MonitorInfo() {}
inline MonitorInfo(int32_t x, int32_t y, uint32_t cx, uint32_t cy)
: x(x), y(y), cx(cx), cy(cy)
{}
};
/* Gets the path of obs-studio specific data files (such as locale) */
bool GetDataFilePath(const char *data, std::string &path);
void GetMonitors(std::vector<MonitorInfo> &monitors);
/* Updates the working directory for OSX application bundles */
bool InitApplicationBundle();

View File

@ -19,11 +19,14 @@
#include <time.h>
#include <obs.hpp>
#include <QGuiApplication>
#include <QMessageBox>
#include <QShowEvent>
#include <QDesktopServices>
#include <QFileDialog>
#include <QDesktopWidget>
#include <QRect>
#include <QScreen>
#include <util/dstr.h>
#include <util/util.hpp>
@ -780,17 +783,18 @@ static const double scaled_vals[] =
bool OBSBasic::InitBasicConfigDefaults()
{
vector<MonitorInfo> monitors;
GetMonitors(monitors);
QList<QScreen*> screens = QGuiApplication::screens();
if (!monitors.size()) {
if (!screens.size()) {
OBSErrorBox(NULL, "There appears to be no monitors. Er, this "
"technically shouldn't be possible.");
return false;
}
uint32_t cx = monitors[0].cx;
uint32_t cy = monitors[0].cy;
QScreen *primaryScreen = QGuiApplication::primaryScreen();
uint32_t cx = primaryScreen->size().width();
uint32_t cy = primaryScreen->size().height();
/* ----------------------------------------------------- */
/* move over mixer values in advanced if older config */
@ -2768,19 +2772,16 @@ static void AddProjectorMenuMonitors(QMenu *parent, QObject *target,
const char *slot)
{
QAction *action;
std::vector<MonitorInfo> monitors;
GetMonitors(monitors);
for (int i = 0; (size_t)i < monitors.size(); i++) {
const MonitorInfo &monitor = monitors[i];
QList<QScreen*> screens = QGuiApplication::screens();
for (int i = 0; i < screens.size(); i++) {
QRect screenGeometry = screens[i]->availableGeometry();
QString str = QString("%1 %2: %3x%4 @ %5,%6").
arg(QTStr("Display"),
QString::number(i),
QString::number((int)monitor.cx),
QString::number((int)monitor.cy),
QString::number((int)monitor.x),
QString::number((int)monitor.y));
QString::number((int)screenGeometry.width()),
QString::number((int)screenGeometry.height()),
QString::number((int)screenGeometry.x()),
QString::number((int)screenGeometry.y()));
action = parent->addAction(str, target, slot);
action->setProperty("monitor", i);

View File

@ -23,6 +23,7 @@
#include <initializer_list>
#include <sstream>
#include <QCompleter>
#include <QGuiApplication>
#include <QLineEdit>
#include <QMessageBox>
#include <QCloseEvent>
@ -30,6 +31,7 @@
#include <QDirIterator>
#include <QVariant>
#include <QTreeView>
#include <QScreen>
#include <QStandardItemModel>
#include <QSpacerItem>
@ -950,8 +952,6 @@ void OBSBasicSettings::LoadRendererList()
#endif
}
Q_DECLARE_METATYPE(MonitorInfo);
static string ResString(uint32_t cx, uint32_t cy)
{
stringstream res;
@ -1097,14 +1097,12 @@ void OBSBasicSettings::LoadResolutionLists()
uint32_t cy = config_get_uint(main->Config(), "Video", "BaseCY");
uint32_t out_cx = config_get_uint(main->Config(), "Video", "OutputCX");
uint32_t out_cy = config_get_uint(main->Config(), "Video", "OutputCY");
vector<MonitorInfo> monitors;
ui->baseResolution->clear();
GetMonitors(monitors);
for (MonitorInfo &monitor : monitors) {
string res = ResString(monitor.cx, monitor.cy);
for (QScreen* screen: QGuiApplication::screens()) {
QSize as = screen->availableSize();
string res = ResString(as.width(), as.height());
ui->baseResolution->addItem(res.c_str());
}

View File

@ -1,6 +1,8 @@
#include <QAction>
#include <QGuiApplication>
#include <QMouseEvent>
#include <QMenu>
#include <QScreen>
#include "window-projector.hpp"
#include "display-helpers.hpp"
#include "qt-wrappers.hpp"
@ -47,11 +49,8 @@ OBSProjector::~OBSProjector()
void OBSProjector::Init(int monitor)
{
std::vector<MonitorInfo> monitors;
GetMonitors(monitors);
MonitorInfo &mi = monitors[monitor];
setGeometry(mi.x, mi.y, mi.cx, mi.cy);
QScreen *screen = QGuiApplication::screens()[monitor];
setGeometry(screen->availableGeometry());
bool alwaysOnTop = config_get_bool(GetGlobalConfig(),
"BasicWindow", "ProjectorAlwaysOnTop");