From 86bf93c9c5584d4a98023dd14e4f12e3b42e6c7f Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Tue, 31 Jan 2017 13:03:51 -0500 Subject: [PATCH] WIP This doesn't currently compile due to referencing some undefined variables. [ci skip] --- src/tools/cursors.linux.cpp | 28 +++++++++++++++++++--- src/tools/winutil.linux.cpp | 48 ++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/tools/cursors.linux.cpp b/src/tools/cursors.linux.cpp index ee52cda0b..878c1cc83 100644 --- a/src/tools/cursors.linux.cpp +++ b/src/tools/cursors.linux.cpp @@ -1,20 +1,42 @@ #include "cursors.hpp" +#include "restypes.hpp" // Include before X11 to avoid macro conflicts in SFML +#include +#include -Cursor::Cursor(fs::path imgPath, float hotSpotX, float hotSpotY) { +Cursor ibeam = XCreateFontCursor(NULL, XC_xterm); + +extern cursor_type current_cursor; + +cCursor::cCursor(fs::path imgPath, float hotSpotX, float hotSpotY) { } -Cursor::~Cursor() { +cCursor::~cCursor() { + Cursor* realPtr = reinterpret_cast(ptr); + XFreeCursor(NULL, *realPtr); + delete realPtr; } -void Cursor::apply() { +void cCursor::apply() { + XDefineCursor(NULL, current_window, *reinterpret_cast(ptr)); } void obscureCursor() { + // TODO: This hides it permanently; it should only hide it until it moves + XUndefineCursor(NULL, current_window); } void set_cursor(cursor_type which_c) { + if(which_c != watch_curs) + current_cursor = which_c; + if(which_c == text_curs) { + XDefineCursor(NULL, current_window, ibeam); + } else { + cCursor& curs = *ResMgr::get(cursors[which_c]); + curs.apply(); + } } void restore_cursor() { + set_cursor(current_cursor); } diff --git a/src/tools/winutil.linux.cpp b/src/tools/winutil.linux.cpp index 95170c5cf..7614bf721 100644 --- a/src/tools/winutil.linux.cpp +++ b/src/tools/winutil.linux.cpp @@ -4,6 +4,7 @@ #include #include #include +#include extern sf::RenderWindow mainPtr; @@ -86,13 +87,58 @@ char keyToChar(sf::Keyboard::Key key, bool isShift) { } std::string get_os_version() { - return "Microsoft Windows XP"; + // TODO: Be more specific + return "Linux/BSD"; } void makeFrontWindow(sf::Window& win) { } void setWindowFloating(sf::Window& win, bool floating) { + // Code adapted from + Atom wmStateAbove = XInternAtom(NULL, "_NET_WM_STATE_ABOVE", true); + if(wmStateAbove != None) { + std::cout << "_NET_WM_STATE_ABOVE has atom of " << long(wmStateAbove) << std::endl; + } else { + std::cerr << "ERROR: cannot find atom for _NET_WM_STATE_ABOVE!\n"; + } + + Atom wmNetWmState = XInternAtom(NULL, "_NET_WM_STATE", true); + if(wmNetWmState != None) { + std::cout << "_NET_WM_STATE has atom of " << long(wmNetWmState) << std::endl; + } else { + std::cerr << "ERROR: cannot find atom for _NET_WM_STATE !\n"; + } + // set window always on top hint + if(wmStateAbove != None) { + XClientMessageEvent xclient; + memset(&xclient, 0, sizeof(xclient)); + + //window = the respective client window + //message_type = _NET_WM_STATE + //format = 32 + //data.l[0] = the action, as listed below + //data.l[1] = first property to alter + //data.l[2] = second property to alter + //data.l[3] = source indication (0-unk,1-normal app,2-pager) + //other data.l[] elements = 0 + + xclient.type = ClientMessage; + xclient.window = mywin; // GDK_WINDOW_XID(window); + xclient.message_type = wmNetWmState; //gdk_x11_get_xatom_by_name_for_display( display, "_NET_WM_STATE" ); + xclient.format = 32; + xclient.data.l[0] = floating ? 1 : 0; + xclient.data.l[1] = wmStateAbove; //gdk_x11_atom_to_xatom_for_display (display, state1); + xclient.data.l[2] = 0; //gdk_x11_atom_to_xatom_for_display (display, state2); + xclient.data.l[3] = 0; + xclient.data.l[4] = 0; + XSendEvent(display, + root, // !! DefaultRootWindow( display ) !!! + False, + SubstructureRedirectMask | SubstructureNotifyMask, + (XEvent *)&xclient + ); + } } void init_fileio() {