Fix launcher having black pixels left behind when windows are moved over it on linux

This commit is contained in:
UnknownShadow200 2018-07-18 04:08:58 +10:00
parent 7f34c26ccd
commit 23065158a6
10 changed files with 95 additions and 24 deletions

View file

@ -28,7 +28,7 @@ namespace InteropPatcher {
public static class Patcher {
public static int Main( string[] args ) {
public static int Main(string[] args) {
try {
if( args.Length == 0 ) {
Console.WriteLine( "Expecting single argument specifying the file to patch" );

View file

@ -26,7 +26,7 @@ namespace Launcher {
public Screen Screen;
/// <summary> Whether the client drawing area needs to be redrawn/presented to the screen. </summary>
public bool Dirty;
public bool Dirty, pendingRedraw;
/// <summary> The specific area/region of the window that needs to be redrawn. </summary>
public Rectangle DirtyArea;
@ -58,9 +58,9 @@ namespace Launcher {
PlatformDrawer platformDrawer;
public void Init() {
Window.Resize += Resize;
Window.FocusedChanged += ForceRedraw;
Window.FocusedChanged += RedrawAll;
Window.WindowStateChanged += Resize;
Window.Redraw += ForceRedraw;
Window.Redraw += RedrawPending;
Keyboard.KeyDown += KeyDown;
ClassicalSharp.Program.CleanupMainDirectory();
@ -103,10 +103,16 @@ namespace Launcher {
void Resize(object sender, EventArgs e) {
UpdateClientSize();
platformDrawer.Resize();
ForceRedraw(sender, e);
RedrawAll(sender, e);
}
void ForceRedraw(object sender, EventArgs e) {
void RedrawPending(object sender, EventArgs e) {
// in case we get multiple of these events
pendingRedraw = true;
Dirty = true;
}
void RedrawAll(object sender, EventArgs e) {
if (Program.ShowingErrorDialog) return;
RedrawBackground();
if (Screen != null) Screen.Resize();
@ -217,6 +223,11 @@ namespace Launcher {
}
void Display() {
if (pendingRedraw) {
RedrawAll(null, null);
pendingRedraw = false;
}
Screen.OnDisplay();
Dirty = false;
@ -235,9 +246,9 @@ namespace Launcher {
public void Dispose() {
Window.Resize -= Resize;
Window.FocusedChanged -= ForceRedraw;
Window.FocusedChanged -= RedrawAll;
Window.WindowStateChanged -= Resize;
Window.Redraw -= ForceRedraw;
Window.Redraw -= RedrawPending;
Keyboard.KeyDown -= KeyDown;
List<FastBitmap> bitmaps = FetchFlagsTask.Bitmaps;

View file

@ -106,6 +106,20 @@ namespace OpenTK.Platform.X11 {
public IntPtr above;
public bool override_redirect;
}
[StructLayout(LayoutKind.Sequential)]
public struct XExposeEvent {
public XEventName type;
public IntPtr serial;
public bool send_event;
public IntPtr display;
public IntPtr window;
public int x;
public int y;
public int width;
public int height;
public int count;
}
[StructLayout(LayoutKind.Sequential)]
public struct XPropertyEvent {
@ -215,6 +229,8 @@ namespace OpenTK.Platform.X11 {
[FieldOffset(0)]
public XConfigureEvent ConfigureEvent;
[FieldOffset(0)]
public XExposeEvent ExposeEvent;
[FieldOffset(0)]
public XPropertyEvent PropertyEvent;
[FieldOffset(0)]
public XSelectionRequestEvent SelectionRequestEvent;

View file

@ -44,7 +44,7 @@ namespace OpenTK.Platform.X11 {
IntPtr net_wm_state_minimized;
IntPtr net_wm_state_fullscreen;
IntPtr net_wm_state_maximized_horizontal;
IntPtr net_wm_state_maximized_vertical;
IntPtr net_wm_state_maximized_vertical;
IntPtr net_wm_icon, net_frame_extents;
IntPtr xa_clipboard, xa_targets, xa_utf8_string, xa_data_sel;
@ -272,6 +272,12 @@ namespace OpenTK.Platform.X11 {
RefreshWindowBounds(ref e);
break;
case XEventName.Expose:
if (e.ExposeEvent.count == 0) {
RaiseRedraw();
}
break;
case XEventName.KeyPress:
ToggleKey(ref e.KeyEvent, true);
int status = API.XLookupString(ref e.KeyEvent, ascii, ascii.Length, null, IntPtr.Zero);

View file

@ -112,7 +112,7 @@ static void AsyncDownloader_Add(String* url, bool priority, String* id, UInt8 ty
}
}
Platform_MutexUnlock(async_pendingMutex);
Platform_EventSet(async_eventHandle);
Platform_EventSignal(async_eventHandle);
}
void AsyncDownloader_GetSkin(STRING_PURE String* id, STRING_PURE String* skinName) {
@ -355,7 +355,7 @@ static void AsyncDownloader_Reset(void) {
AsyncRequestList_Free(&async_pending);
}
Platform_MutexUnlock(async_pendingMutex);
Platform_EventSet(async_eventHandle);
Platform_EventSignal(async_eventHandle);
}
static void AsyncDownloader_Free(void) {

View file

@ -77,7 +77,7 @@ void Platform_MutexUnlock(void* handle);
void* Platform_EventCreate(void);
void Platform_EventFree(void* handle);
void Platform_EventSet(void* handle);
void Platform_EventSignal(void* handle);
void Platform_EventWait(void* handle);
typedef Int64 Stopwatch;

View file

@ -341,7 +341,7 @@ void Platform_EventFree(void* handle) {
}
}
void Platform_EventSet(void* handle) {
void Platform_EventSignal(void* handle) {
SetEvent((HANDLE)handle);
}

View file

@ -9,6 +9,7 @@
#include "Entity.h"
#include "ExtMath.h"
#include "Physics.h"
#include "Game.h"
void World_Reset(void) {
Platform_MemFree(&World_Blocks);
@ -19,7 +20,12 @@ void World_Reset(void) {
Random rnd;
Random_InitFromCurrentTime(&rnd);
/* add a bit of randomness for uuid */
Int32 i;
for (i = 0; i < Game_Username.length; i++) {
Random_Next(&rnd, Game_Username.buffer[i] + 3);
}
for (i = 0; i < 16; i++) {
World_Uuid[i] = Random_Next(&rnd, 256);
}

View file

@ -35,8 +35,14 @@ static void Platform_UnicodeExpand(UInt8* dst, STRING_PURE String* src) {
*dst = NULL;
}
void Platform_Init(void) { }
void Platform_Free(void) { }
pthread_mutex_t event_mutex;
void Platform_Init(void) {
pthread_mutex_init(&event_mutex, NULL);
}
void Platform_Free(void) {
pthread_mutex_destroy(&event_mutex);
}
void Platform_Exit(ReturnCode code) { exit(code); }
STRING_PURE String Platform_GetCommandLineArgs(void);
@ -264,10 +270,30 @@ void Platform_MutexUnlock(void* handle) {
ErrorHandler_CheckOrFail(result, "Unlocking mutex");
}
void* Platform_EventCreate(void);
void Platform_EventFree(void* handle);
void Platform_EventSet(void* handle);
void Platform_EventWait(void* handle);
pthread_cond_t condList[2]; Int32 condIndex;
void* Platform_EventCreate(void) {
if (condIndex == Array_Elems(condList)) ErrorHandler_Fail("Cannot allocate event");
pthread_cond_t* ptr = &condList[condIndex];
int result = pthread_cond_init(ptr, NULL);
ErrorHandler_CheckOrFail(result, "Creating event");
condIndex++; return ptr;
}
void Platform_EventFree(void* handle) {
int result = pthread_cond_destroy((pthread_cond_t*)handle);
ErrorHandler_CheckOrFail(result, "Destroying event");
}
void Platform_EventSignal(void* handle) {
int result = pthread_cond_signal((pthread_cond_t*)handle);
ErrorHandler_CheckOrFail(result, "Signalling event");
}
void Platform_EventWait(void* handle) {
int result = pthread_cond_wait((pthread_cond_t*)handle, event_mutex);
ErrorHandler_CheckOrFail(result, "Waiting event");
}
void Stopwatch_Start(Stopwatch* timer);
Int32 Stopwatch_ElapsedMicroseconds(Stopwatch* timer);

View file

@ -473,12 +473,18 @@ void Window_ProcessEvents(void) {
break;
case ConfigureNotify:
RefreshWindowBounds(&e);
Window_RefreshBounds(&e);
break;
case Expose:
if (e.xexpose.count == 0) {
Event_RaiseVoid(&WindowEvents_Redraw);
}
break;
case KeyPress:
{
ToggleKey(&e.xkey, true);
Window_ToggleKey(&e.xkey, true);
UInt8 data[16]; UInt8 convBuffer[16];
int status = XLookupString(&e.xkey, data, Array_Elems(data), NULL, NULL);
@ -493,7 +499,7 @@ void Window_ProcessEvents(void) {
case KeyRelease:
/* TODO: raise KeyPress event. Use code from */
/* http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Keyboard.cs?view=markup */
ToggleKey(&e.xkey, false);
Window_ToggleKey(&e.xkey, false);
break;
case ButtonPress:
@ -538,7 +544,7 @@ void Window_ProcessEvents(void) {
case PropertyNotify:
if (e.xproperty.atom == net_wm_state) {
RaiseWindowStateChanged();
Event_RaiseVoid(&WindowEvents_StateChanged);
}
//if (e.xproperty.atom == net_frame_extents) {
@ -763,7 +769,7 @@ static XVisualInfo GLContext_SelectVisual(struct GraphicsMode* mode) {
visual = glXChooseVisual(win_display, win_screen, attribs);
}
if (visual == NULL) {
ErorrHandler_Fail("Requested GraphicsMode not available.");
ErrorHandler_Fail("Requested GraphicsMode not available.");
}
XVisualInfo info = *visual;