Skip to content

Commit

Permalink
added Linux support / some more cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
WarmUpTill committed Oct 29, 2017
1 parent 6d024b4 commit 2e7ea7d
Show file tree
Hide file tree
Showing 4 changed files with 333 additions and 23 deletions.
18 changes: 10 additions & 8 deletions CMakeLists.txt
Expand Up @@ -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}
Expand Down Expand Up @@ -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
Expand Down
322 changes: 322 additions & 0 deletions advanced-scene-switcher-nix.cpp
@@ -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;
}


14 changes: 0 additions & 14 deletions scene-transitions.cpp
@@ -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()
{
Expand Down
2 changes: 1 addition & 1 deletion utility.hpp
@@ -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;
Expand Down

0 comments on commit 2e7ea7d

Please sign in to comment.