added Linux support / some more cleanup

This commit is contained in:
WarmUpTill 2017-10-29 12:44:04 +01:00 committed by GitHub
parent 6d024b459e
commit 2e7ea7db01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 333 additions and 23 deletions

View File

@ -5,11 +5,11 @@ if(APPLE)
include_directories(${COCOA})
endif()
#if(UNIX)
# find_package(X11 REQUIRED)
# link_libraries(${X11_LIBRARIES})
# include_directories(${X11_INCLUDE_DIR})
#endif()
if(UNIX)
find_package(X11 REQUIRED)
link_libraries(${X11_LIBRARIES})
include_directories(${X11_INCLUDE_DIR})
endif()
set(advanced-scene-switcher_HEADERS
${advanced-scene-switcher_HEADERS}
@ -50,9 +50,11 @@ elseif(APPLE)
set(advanced-scene-switcher_PLATFORM_LIBS
${COCOA})
#else()
# set(advanced-scene-switcher_PLATFORM_SOURCES
# advanced-scene-switcher-nix.cpp)
else()
set(advanced-scene-switcher_PLATFORM_SOURCES
advanced-scene-switcher-nix.cpp)
set(advanced-scene-switcher_PLATFORM_LIBS
Xss)
endif()
qt5_wrap_ui(advanced-scene-switcher_UI_HEADERS

View File

@ -0,0 +1,322 @@
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/extensions/scrnsaver.h>
#undef Bool
#undef CursorShape
#undef Expose
#undef KeyPress
#undef KeyRelease
#undef FocusIn
#undef FocusOut
#undef FontChange
#undef None
#undef Status
#undef Unsorted
#include <util/platform.h>
#include "advanced-scene-switcher.hpp"
using namespace std;
static Display* xdisplay = 0;
Display *disp()
{
if (!xdisplay)
xdisplay = XOpenDisplay(NULL);
return xdisplay;
}
void cleanupDisplay()
{
if (!xdisplay)
return;
XCloseDisplay(xdisplay);
xdisplay = 0;
}
static bool ewmhIsSupported()
{
Display *display = disp();
Atom netSupportingWmCheck = XInternAtom(display,
"_NET_SUPPORTING_WM_CHECK", true);
Atom actualType;
int format = 0;
unsigned long num = 0, bytes = 0;
unsigned char *data = NULL;
Window ewmh_window = 0;
int status = XGetWindowProperty(
display,
DefaultRootWindow(display),
netSupportingWmCheck,
0L,
1L,
false,
XA_WINDOW,
&actualType,
&format,
&num,
&bytes,
&data);
if (status == Success) {
if (num > 0) {
ewmh_window = ((Window*)data)[0];
}
if (data) {
XFree(data);
data = NULL;
}
}
if (ewmh_window) {
status = XGetWindowProperty(
display,
ewmh_window,
netSupportingWmCheck,
0L,
1L,
false,
XA_WINDOW,
&actualType,
&format,
&num,
&bytes,
&data);
if (status != Success || num == 0 ||
ewmh_window != ((Window*)data)[0]) {
ewmh_window = 0;
}
if (status == Success && data) {
XFree(data);
}
}
return ewmh_window != 0;
}
static std::vector<Window> getTopLevelWindows()
{
std::vector<Window> res;
res.resize(0);
if (!ewmhIsSupported()) {
return res;
}
Atom netClList = XInternAtom(disp(), "_NET_CLIENT_LIST", true);
Atom actualType;
int format;
unsigned long num, bytes;
Window* data = 0;
for (int i = 0; i < ScreenCount(disp()); ++i) {
Window rootWin = RootWindow(disp(), i);
int status = XGetWindowProperty(
disp(),
rootWin,
netClList,
0L,
~0L,
false,
AnyPropertyType,
&actualType,
&format,
&num,
&bytes,
(uint8_t**)&data);
if (status != Success) {
continue;
}
for (unsigned long i = 0; i < num; ++i)
res.emplace_back(data[i]);
XFree(data);
}
return res;
}
static std::string GetWindowTitle(size_t i)
{
Window w = getTopLevelWindows().at(i);
std::string windowTitle;
char* name;
int status = XFetchName(disp(), w, &name);
if (status >= Success && name != nullptr)
{
std::string str(name);
windowTitle = str;
}
XFree(name);
return windowTitle;
}
void GetWindowList(vector<string> &windows)
{
windows.resize(0);
for (size_t i = 0; i < getTopLevelWindows().size(); ++i){
if (GetWindowTitle(i) != "")
windows.emplace_back(GetWindowTitle(i));
}
}
void GetCurrentWindowTitle(string &title)
{
if (!ewmhIsSupported()) {
return;
}
Atom active = XInternAtom(disp(), "_NET_ACTIVE_WINDOW", true);
Atom actualType;
int format;
unsigned long num, bytes;
Window* data = 0;
char* name;
Window rootWin = RootWindow(disp(), 0);
XGetWindowProperty(
disp(),
rootWin,
active,
0L,
~0L,
false,
AnyPropertyType,
&actualType,
&format,
&num,
&bytes,
(uint8_t**)&data);
int status = XFetchName(disp(), data[0], &name);
if (status >= Success && name != nullptr) {
std::string str(name);
title = str;
}
XFree(name);
}
pair<int, int> getCursorPos()
{
pair<int, int> pos(0, 0);
Display *dpy;
Window root;
Window ret_root;
Window ret_child;
int root_x;
int root_y;
int win_x;
int win_y;
unsigned int mask;
dpy = XOpenDisplay(NULL);
root = XDefaultRootWindow(dpy);
if(XQueryPointer(dpy, root, &ret_root, &ret_child, &root_x, &root_y,
&win_x, &win_y, &mask))
{
pos = pair<int, int> (root_x,root_y);
}
return pos;
}
bool isFullscreen()
{
if (!ewmhIsSupported()) {
return false;
}
Atom active = XInternAtom(disp(), "_NET_ACTIVE_WINDOW", true);
Atom actualType;
int format;
unsigned long num, bytes;
Window* data = 0;
Window rootWin = RootWindow(disp(), 0);
XGetWindowProperty(
disp(),
rootWin,
active,
0L,
~0L,
false,
AnyPropertyType,
&actualType,
&format,
&num,
&bytes,
(uint8_t**)&data);
XWindowAttributes window_attributes_return;
XWindowAttributes screen_attributes_return;
XGetWindowAttributes(disp(), rootWin, &screen_attributes_return);
XGetWindowAttributes(disp(), data[0], &window_attributes_return);
//menu bar is always 24 pixels in height
return (window_attributes_return.width >= screen_attributes_return.width &&
window_attributes_return.height + 24 >= screen_attributes_return.height) ? true : false;
}
//exe switch is not quite what is expected but it works for now
void GetProcessList(QStringList &processes)
{
processes.clear();
for (size_t i = 0; i < getTopLevelWindows().size(); ++i){
string s = GetWindowTitle(i);
if (s != "")
processes << QString::fromStdString(s);
}
}
bool isInFocus(const QString &exeToCheck)
{
string curWindow;
GetCurrentWindowTitle(curWindow);
return (QString::compare(
QString::fromStdString(curWindow),
exeToCheck,
Qt::CaseInsensitive) == 0) ? true : false;
}
int secondsSinceLastInput()
{
time_t idle_time;
static XScreenSaverInfo *mit_info;
Display *display;
int screen;
mit_info = XScreenSaverAllocInfo();
if((display=XOpenDisplay(NULL)) == NULL)
{
return(-1);
}
screen = DefaultScreen(display);
XScreenSaverQueryInfo(display, RootWindow(display,screen), mit_info);
idle_time = (mit_info->idle) / 1000;
XFree(mit_info);
XCloseDisplay(display);
return idle_time;
}

View File

@ -1,18 +1,4 @@
#include "advanced-scene-switcher.hpp"
#if 1
#include <Windows.h>
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
#endif
void SceneSwitcher::on_transitionsAdd_clicked()
{

View File

@ -1,6 +1,6 @@
#pragma once
#include <obs.hpp>
#include <qstring>
#include <QString>
#include <obs-frontend-api.h>
#include "switcher-data-structs.hpp"
using namespace std;