diff options
-rw-r--r-- | README.md | 18 | ||||
-rw-r--r-- | core/bind/core_bind.cpp | 41 | ||||
-rw-r--r-- | core/bind/core_bind.h | 9 | ||||
-rw-r--r-- | core/os/os.h | 11 | ||||
-rw-r--r-- | demos/misc/window_management/control.gd | 39 | ||||
-rw-r--r-- | demos/misc/window_management/engine.cfg | 5 | ||||
-rw-r--r-- | demos/misc/window_management/icon.png | bin | 0 -> 3639 bytes | |||
-rw-r--r-- | demos/misc/window_management/icon.png.flags | 1 | ||||
-rw-r--r-- | demos/misc/window_management/window_management.scn | bin | 0 -> 3276 bytes | |||
-rw-r--r-- | main/main.cpp | 1 | ||||
-rw-r--r-- | platform/x11/os_x11.cpp | 173 | ||||
-rw-r--r-- | platform/x11/os_x11.h | 17 |
12 files changed, 284 insertions, 31 deletions
@@ -1,3 +1,21 @@ +### x11-window-management branch + +#### New GDScript Methods for the OS Class: +* int OS.get_screen_count() +* Vector2 OS.get_screen_size(int screen=0) +* Vector2 OS.get_window_position() +* void OS.set_window_position(Vector2 position) +* Vector2 OS.get_window_size() +* void OS.set_window_size(Vector2 size) +* void OS.set_fullscreen(bool enabled, int screen=0) +* bool OS.is_fullscreen() + +#### Demo +A demo/test is available at "demos/misc/window-management" + +#### Warning +Just only works for X11. It breaks other platforms at the moment. +  ### The Engine diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 0c5d21b4f6..47bfba1cbb 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -176,6 +176,38 @@ bool _OS::is_video_mode_fullscreen(int p_screen) const { } +int _OS::get_screen_count() const { + return OS::get_singleton()->get_screen_count(); +} + +Size2 _OS::get_screen_size(int p_screen) const { + return OS::get_singleton()->get_screen_size(p_screen); +} + +Point2 _OS::get_window_position() const { + return OS::get_singleton()->get_window_position(); +} + +void _OS::set_window_position(const Point2& p_position) { + OS::get_singleton()->set_window_position(p_position); +} + +Size2 _OS::get_window_size() const { + return OS::get_singleton()->get_window_size(); +} + +void _OS::set_window_size(const Size2& p_size) { + OS::get_singleton()->set_window_size(p_size); +} + +void _OS::set_fullscreen(bool p_enabled,int p_screen) { + OS::get_singleton()->set_fullscreen(p_enabled, p_screen); +} + +bool _OS::is_fullscreen() const { + return OS::get_singleton()->is_fullscreen(); +} + void _OS::set_use_file_access_save_and_swap(bool p_enable) { FileAccess::set_backup_save(p_enable); @@ -632,6 +664,15 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_video_mode_resizable","screen"),&_OS::is_video_mode_resizable,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("get_fullscreen_mode_list","screen"),&_OS::get_fullscreen_mode_list,DEFVAL(0)); + ObjectTypeDB::bind_method(_MD("get_screen_count"),&_OS::get_screen_count); + ObjectTypeDB::bind_method(_MD("get_screen_size"),&_OS::get_screen_size,DEFVAL(0)); + ObjectTypeDB::bind_method(_MD("get_window_position"),&_OS::get_window_position); + ObjectTypeDB::bind_method(_MD("set_window_position"),&_OS::set_window_position); + ObjectTypeDB::bind_method(_MD("get_window_size"),&_OS::get_window_size); + ObjectTypeDB::bind_method(_MD("set_window_size"),&_OS::set_window_size); + ObjectTypeDB::bind_method(_MD("set_fullscreen","enabled","screen"),&_OS::set_fullscreen,DEFVAL(0)); + ObjectTypeDB::bind_method(_MD("is_fullscreen"),&_OS::is_fullscreen); + ObjectTypeDB::bind_method(_MD("set_iterations_per_second","iterations_per_second"),&_OS::set_iterations_per_second); ObjectTypeDB::bind_method(_MD("get_iterations_per_second"),&_OS::get_iterations_per_second); ObjectTypeDB::bind_method(_MD("set_target_fps","target_fps"),&_OS::set_target_fps); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 12a4ae86eb..2a87f85ec7 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -108,6 +108,15 @@ public: bool is_video_mode_resizable(int p_screen=0) const; Array get_fullscreen_mode_list(int p_screen=0) const; + virtual int get_screen_count() const; + virtual Size2 get_screen_size(int p_screen=0) const; + virtual Point2 get_window_position() const; + virtual void set_window_position(const Point2& p_position); + virtual Size2 get_window_size() const; + virtual void set_window_size(const Size2& p_size); + void set_fullscreen(bool p_enabled, int p_screen=0); + bool is_fullscreen() const; + Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); bool native_video_is_playing(); void native_video_pause(); diff --git a/core/os/os.h b/core/os/os.h index d4deff2f5e..edb5d57c5f 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -73,7 +73,7 @@ public: bool fullscreen; bool resizable; float get_aspect() const { return (float)width/(float)height; } - VideoMode(int p_width=640,int p_height=480,bool p_fullscreen=false, bool p_resizable = true) { width=p_width; height=p_height; fullscreen=p_fullscreen; resizable = p_resizable; } + VideoMode(int p_width=640,int p_height=480,bool p_fullscreen=false, bool p_resizable = true) {width=p_width; height=p_height; fullscreen=p_fullscreen; resizable = p_resizable; } }; protected: friend class Main; @@ -149,6 +149,15 @@ public: virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0)=0; virtual VideoMode get_video_mode(int p_screen=0) const=0; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const=0; + + virtual int get_screen_count() const=0; + virtual Size2 get_screen_size(int p_screen=0) const=0; + virtual Point2 get_window_position() const=0; + virtual void set_window_position(const Point2& p_position)=0; + virtual Size2 get_window_size() const=0; + virtual void set_window_size(const Size2 p_size)=0; + virtual void set_fullscreen(bool p_enabled,int p_screen=0)=0; + virtual bool is_fullscreen() const=0; virtual void set_iterations_per_second(int p_ips); virtual int get_iterations_per_second() const; diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd new file mode 100644 index 0000000000..3e74f24e42 --- /dev/null +++ b/demos/misc/window_management/control.gd @@ -0,0 +1,39 @@ + +extends Control + +func _fixed_process(delta): + if(OS.is_fullscreen()): + get_node("Label_Fullscreen").set_text("Mode:\nFullscreen") + else: + get_node("Label_Fullscreen").set_text("Mode:\nWindowed") + + get_node("Label_Position").set_text( str("Position:\n", OS.get_window_position() ) ) + + get_node("Label_Size").set_text(str("Size:\n", OS.get_window_size() ) ) + + get_node("Label_Screen_Count").set_text( str("Screens:\n", OS.get_screen_count() ) ) + + get_node("Label_Screen0_Resolution").set_text( str("Screen0 Resolution:\n", OS.get_screen_size() ) ) + + if(OS.get_screen_count() > 1): + get_node("Label_Screen1_Resolution").show() + get_node("Label_Screen1_Resolution").set_text( str("Screen0 Resolution:\n", OS.get_screen_size(1) ) ) + + +func _ready(): + set_fixed_process(true) + + +func _on_Fullscreen_toggled( pressed ): + if(pressed): + OS.set_fullscreen(true) + else: + OS.set_fullscreen(false) + + +func _on_Button_MoveTo_pressed(): + OS.set_window_position( Vector2(100,100) ) + + +func _on_Button_Resize_pressed(): + OS.set_window_size( Vector2(1024,768) ) diff --git a/demos/misc/window_management/engine.cfg b/demos/misc/window_management/engine.cfg new file mode 100644 index 0000000000..7b6dddce96 --- /dev/null +++ b/demos/misc/window_management/engine.cfg @@ -0,0 +1,5 @@ +[application] + +name="window_management" +main_scene="res://window_management.scn" +icon="icon.png" diff --git a/demos/misc/window_management/icon.png b/demos/misc/window_management/icon.png Binary files differnew file mode 100644 index 0000000000..0c422e37b0 --- /dev/null +++ b/demos/misc/window_management/icon.png diff --git a/demos/misc/window_management/icon.png.flags b/demos/misc/window_management/icon.png.flags new file mode 100644 index 0000000000..5130fd1aab --- /dev/null +++ b/demos/misc/window_management/icon.png.flags @@ -0,0 +1 @@ +gen_mipmaps=false diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn Binary files differnew file mode 100644 index 0000000000..6eaf62ff9f --- /dev/null +++ b/demos/misc/window_management/window_management.scn diff --git a/main/main.cpp b/main/main.cpp index f0e376a045..27d7d97e85 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -627,7 +627,6 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas } } - GLOBAL_DEF("display/width",video_mode.width); GLOBAL_DEF("display/height",video_mode.height); GLOBAL_DEF("display/fullscreen",video_mode.fullscreen); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index a40af8d2a9..063fb17c26 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -162,6 +162,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi // maybe contextgl wants to be in charge of creating the window //print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height)); #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) + context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) ); context_gl->initialize(); @@ -181,33 +182,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi // borderless fullscreen window mode if (current_videomode.fullscreen) { - // needed for lxde/openbox, possibly others - Hints hints; - Atom property; - hints.flags = 2; - hints.decorations = 0; - property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); - XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); - XMapRaised(x11_display, x11_window); - XWindowAttributes xwa; - XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); - XMoveResizeWindow(x11_display, x11_window, 0, 0, xwa.width, xwa.height); - - // code for netwm-compliants - XEvent xev; - Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); - Atom fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False); - - memset(&xev, 0, sizeof(xev)); - xev.type = ClientMessage; - xev.xclient.window = x11_window; - xev.xclient.message_type = wm_state; - xev.xclient.format = 32; - xev.xclient.data.l[0] = 1; - xev.xclient.data.l[1] = fullscreen; - xev.xclient.data.l[2] = 0; - - XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); + set_wm_border(false); + set_wm_fullscreen(true); } // disable resizeable window @@ -520,6 +496,149 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) cons } +void OS_X11::set_wm_border(bool p_enabled) { + // needed for lxde/openbox, possibly others + Hints hints; + Atom property; + hints.flags = 2; + hints.decorations = p_enabled ? 1L : 0L;; + property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); + XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); + XMapRaised(x11_display, x11_window); + XMoveResizeWindow(x11_display, x11_window, 0, 0, current_videomode.width, current_videomode.height); +} + +void OS_X11::set_wm_fullscreen(bool p_enabled) { + // code for netwm-compliants + XEvent xev; + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = p_enabled ? 1L : 0L; + xev.xclient.data.l[1] = wm_fullscreen; + xev.xclient.data.l[2] = 0; + + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); +} + +int OS_X11::get_screen_count() const { + return XScreenCount(x11_display); +} + +Size2 OS_X11::get_screen_size(int p_screen) const { + Window root = XRootWindow(x11_display, p_screen); + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, root, &xwa); + return Size2i(xwa.width, xwa.height); +} + + +Point2 OS_X11::get_window_position() const { + int x,y; + XWindowAttributes xwa; + Window child; + XTranslateCoordinates( x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child); + XGetWindowAttributes(x11_display, x11_window, &xwa); + + return Point2i(x,y); +} + +void OS_X11::set_window_position(const Point2& p_position) { + + if( current_videomode.fullscreen ) + return; + + // _NET_FRAME_EXTENTS + Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + //long *extends; + int result; + + result = XGetWindowProperty( + x11_display, + x11_window, + property, + 0, + 32, + False, + AnyPropertyType, + &type, + &format, + &len, + &remaining, + &data + ); + + long left = 0L; + long top = 0L; + + if( result == Success ) { + long *extends = (long *) data; + + left = extends[0]; + top = extends[2]; + + XFree(data); + data = NULL; + } + + XMoveWindow(x11_display,x11_window,p_position.x - left,p_position.y - top); +} + +Size2 OS_X11::get_window_size() const { + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, x11_window, &xwa); + return Size2i(xwa.width, xwa.height); +} + +void OS_X11::set_window_size(const Size2 p_size) { + if( current_videomode.fullscreen ) + return; + + XResizeWindow(x11_display, x11_window, p_size.x, p_size.y); +} + +void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { + + if(p_enabled && current_videomode.fullscreen) + return; + + if(p_enabled) { + pre_videomode = current_videomode; + + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); + + current_videomode.fullscreen = True; + current_videomode.width = xwa.width; + current_videomode.height = xwa.height; + + set_wm_border(false); + set_wm_fullscreen(true); + } else { + current_videomode.fullscreen = False; + current_videomode.width = pre_videomode.width; + current_videomode.height = pre_videomode.height; + + set_wm_fullscreen(false); + set_wm_border(true); + } + + visual_server->init(); +} + +bool OS_X11::is_fullscreen() const { + return current_videomode.fullscreen; +} InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) { diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index dd2476ec1b..a38d511003 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -73,6 +73,7 @@ class OS_X11 : public OS_Unix { Rasterizer *rasterizer; VisualServer *visual_server; VideoMode current_videomode; + VideoMode pre_videomode; List<String> args; Window x11_window; MainLoop *main_loop; @@ -159,6 +160,8 @@ class OS_X11 : public OS_Unix { int joystick_count; Joystick joysticks[JOYSTICKS_MAX]; + void set_wm_border(bool p_enabled); + void set_wm_fullscreen(bool p_enabled); protected: @@ -166,8 +169,8 @@ protected: virtual const char * get_video_driver_name(int p_driver) const; virtual VideoMode get_default_video_mode() const; - virtual int get_audio_driver_count() const; - virtual const char * get_audio_driver_name(int p_driver) const; + virtual int get_audio_driver_count() const; + virtual const char * get_audio_driver_name(int p_driver) const; virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver); virtual void finalize(); @@ -178,6 +181,7 @@ protected: void process_joysticks(); void close_joystick(int p_id = -1); + public: virtual String get_name(); @@ -213,6 +217,15 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const; + virtual int get_screen_count() const; + virtual Size2 get_screen_size(int p_screen=0) const; + virtual Point2 get_window_position() const; + virtual void set_window_position(const Point2& p_position); + virtual Size2 get_window_size() const; + virtual void set_window_size(const Size2 p_size); + virtual void set_fullscreen(bool p_enabled,int p_screen=0); + virtual bool is_fullscreen() const; + virtual void move_window_to_foreground(); void run(); |