mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 07:21:02 +00:00
Workarounds to re-display windows on MS Windows.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@38367 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
dec8b7b7e4
commit
dd0c80e167
4 changed files with 150 additions and 89 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
2015-02-27 Germán Arias <germanandre@gmx.es>
|
||||
|
||||
* Source/cairo/CairoContext.m (-flushGraphics:):
|
||||
* Source/cairo/Win32CairoSurface.m (-initWithDevice:): Apply fix
|
||||
from TestPlant branch to solve problem with windows with backing
|
||||
store type NSBackingStoreRetained, which are not displayed correclty
|
||||
on MS Windows. With this fix those windows are displayed as
|
||||
buffered windows.
|
||||
* Source/win32/WIN32Server.m (-setWindowdevice:forContext:): The
|
||||
windows with autodisplay set to NO aren't displayed correctly on
|
||||
Windows, no matter the backing store type used. And trying to
|
||||
redisplay these windows here in the server not takes effect. So if
|
||||
the window have set autodisplay to NO, we change it to YES before
|
||||
create the window. This problem affects the tooltips, but this
|
||||
solution is different to the one used in the TestPlant branch.
|
||||
Because that solution involves changes in the side of GUI.
|
||||
|
||||
2014-10-25 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/cairo/CairoGState.m (-compositeGState:...fraction:):
|
||||
|
|
|
@ -60,6 +60,8 @@
|
|||
#elif BUILD_SERVER == SERVER_win32
|
||||
# include "cairo/Win32CairoGState.h"
|
||||
# include <windows.h>
|
||||
# include "win32/WIN32Server.h"
|
||||
# include "win32/WIN32Geometry.h"
|
||||
# define _CAIRO_GSTATE_CLASSNAME Win32CairoGState
|
||||
# ifdef USE_GLITZ
|
||||
# define _CAIRO_SURFACE_CLASSNAME Win32CairoGlitzSurface
|
||||
|
@ -107,6 +109,20 @@
|
|||
- (void) flushGraphics
|
||||
{
|
||||
// FIXME: Why is this here? When is it called?
|
||||
// Comments added 07/20/2013 to address the above question after
|
||||
// further debugging cairo/MSwindows non-retained backing store type:
|
||||
// This is called from NSWindow/flushWindow for the non-retained backing
|
||||
// store case. This code originally seems to have been added due to the
|
||||
// non-retained backing store type NOT showing up on XWindows/Cairo
|
||||
// combination and added this XFlush call to handle this case.
|
||||
|
||||
// For MSWindows a similar problem seems to occur. However, the only
|
||||
// equivalent to XFlush on MSWindows is GdiFlush, which doesn't cause
|
||||
// the window to re-display properly. So, on MSWindows, the non-retained
|
||||
// cairo backend surface is currently excluded from the build and we
|
||||
// handle it as a buffered window expose event for now.
|
||||
// FIXME: Anyone know how this can be handled/fixed correctly...
|
||||
|
||||
#if BUILD_SERVER == SERVER_x11
|
||||
XFlush([(XGServer *)server xDisplay]);
|
||||
#elif BUILD_SERVER == SERVER_win32
|
||||
|
@ -115,9 +131,16 @@
|
|||
[CGSTATE GSCurrentSurface: &surface : NULL : NULL];
|
||||
if ((surface != nil) && ([surface surface] != NULL))
|
||||
{
|
||||
cairo_surface_flush([surface surface]);
|
||||
// Non-retained backing store types currently unsupported on MSWindows...
|
||||
// Currently handling such windows as buffered and invoking the handle
|
||||
// expose event processing...
|
||||
RECT rect;
|
||||
HWND hwnd = surface->gsDevice;
|
||||
GetClientRect(hwnd, &rect);
|
||||
NSRect frame = MSWindowRectToGS((WIN32Server*)GSCurrentServer(), hwnd, rect);
|
||||
[[self class] handleExposeRect: frame forDriver: surface];
|
||||
}
|
||||
#endif // BUILD_SERVER = SERVER_x11
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,101 +37,107 @@
|
|||
|
||||
- (id) initWithDevice: (void *)device
|
||||
{
|
||||
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)device, GWL_USERDATA);
|
||||
HDC hDC = GetDC((HWND)device);
|
||||
if (self)
|
||||
{
|
||||
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)device, GWL_USERDATA);
|
||||
HDC hDC = GetDC((HWND)device);
|
||||
|
||||
// Save/set initial state...
|
||||
gsDevice = device;
|
||||
_surface = NULL;
|
||||
// Save/set initial state...
|
||||
gsDevice = device;
|
||||
_surface = NULL;
|
||||
|
||||
if (hDC == NULL)
|
||||
{
|
||||
NSWarnMLog(@"Win32CairoSurface line: %d : no device context", __LINE__);
|
||||
if (hDC == NULL)
|
||||
{
|
||||
NSWarnMLog(@"Win32CairoSurface line: %d : no device context", __LINE__);
|
||||
|
||||
// And deallocate ourselves...
|
||||
DESTROY(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create the cairo surfaces...
|
||||
// NSBackingStoreRetained works like Buffered since 10.5 (See apple docs)...
|
||||
// NOTE: According to Apple docs NSBackingStoreBuffered should be the only one
|
||||
// ever used anymore....others are NOT recommended...
|
||||
if (win && (win->type == NSBackingStoreNonretained))
|
||||
{
|
||||
// This is the raw DC surface...
|
||||
_surface = cairo_win32_surface_create(hDC);
|
||||
|
||||
// Check for error...
|
||||
if (cairo_surface_status(_surface) != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
// Output the surface create error...
|
||||
cairo_status_t status = cairo_surface_status(_surface);
|
||||
NSWarnMLog(@"surface create FAILED - status: %s\n", cairo_status_to_string(status));
|
||||
|
||||
// Destroy the initial surface created...
|
||||
cairo_surface_destroy(_surface);
|
||||
|
||||
// And deallocate ourselves...
|
||||
DESTROY(self);
|
||||
}
|
||||
}
|
||||
// And deallocate ourselves...
|
||||
DESTROY(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSSize csize = [self size];
|
||||
|
||||
// This is the raw DC surface...
|
||||
cairo_surface_t *window = cairo_win32_surface_create(hDC);
|
||||
cairo_status_t status = cairo_surface_status(window);
|
||||
|
||||
// Check for error...
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
// Output the surface create error...
|
||||
NSWarnMLog(@"surface create FAILED - status: %s\n", cairo_status_to_string(status));
|
||||
{
|
||||
// Create the cairo surfaces...
|
||||
// NSBackingStoreRetained works like Buffered since 10.5 (See apple docs)...
|
||||
// NOTE: According to Apple docs NSBackingStoreBuffered should be the only one
|
||||
// ever used anymore....others are NOT recommended...
|
||||
if (win && (win->type == NSBackingStoreNonretained))
|
||||
{
|
||||
// This is the raw DC surface...
|
||||
_surface = cairo_win32_surface_create(hDC);
|
||||
|
||||
// Check for error...
|
||||
if (cairo_surface_status(_surface) != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
// Output the surface create error...
|
||||
cairo_status_t status = cairo_surface_status(_surface);
|
||||
NSWarnMLog(@"surface create FAILED - status: %s\n", cairo_status_to_string(status));
|
||||
|
||||
// And deallocate ourselves...
|
||||
DESTROY(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
// and this is the in-memory DC surface...surface owns its DC...
|
||||
// NOTE: For some reason we get an init sequence with zero width/height,
|
||||
// which creates problems in the cairo layer. It tries to clear
|
||||
// the 'similar' surface it's creating, and with a zero width/height
|
||||
// it incorrectly thinks the clear failed...so we will init with
|
||||
// a minimum size of 1 for width/height...
|
||||
_surface = cairo_surface_create_similar(window, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
MAX(1, csize.width),
|
||||
MAX(1, csize.height));
|
||||
status = cairo_surface_status(_surface);
|
||||
// Destroy the initial surface created...
|
||||
cairo_surface_destroy(_surface);
|
||||
|
||||
// And deallocate ourselves...
|
||||
DESTROY(self);
|
||||
|
||||
// Check for error...
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
// Output the surface create error...
|
||||
NSWarnMLog(@"surface create FAILED - status: %s\n", cairo_status_to_string(status));
|
||||
|
||||
// Destroy the surface created...
|
||||
cairo_surface_destroy(_surface);
|
||||
|
||||
// And deallocate ourselves...
|
||||
DESTROY(self);
|
||||
}
|
||||
}
|
||||
// Release the device context...
|
||||
ReleaseDC(device, hDC);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSSize csize = [self size];
|
||||
|
||||
// Destroy the initial surface created...
|
||||
cairo_surface_destroy(window);
|
||||
}
|
||||
|
||||
// Release the device context...
|
||||
ReleaseDC((HWND)device, hDC);
|
||||
// This is the raw DC surface...
|
||||
cairo_surface_t *window = cairo_win32_surface_create(hDC);
|
||||
|
||||
if (win && self)
|
||||
{
|
||||
// We need this for handleExposeEvent in WIN32Server...
|
||||
win->surface = (void*)self;
|
||||
}
|
||||
// Check for error...
|
||||
if (cairo_surface_status(window) != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
// Output the surface create error...
|
||||
cairo_status_t status = cairo_surface_status(window);
|
||||
NSWarnMLog(@"surface create FAILED - status: %s\n", cairo_status_to_string(status));
|
||||
|
||||
// And deallocate ourselves...
|
||||
DESTROY(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
// and this is the in-memory DC surface...surface owns its DC...
|
||||
// NOTE: For some reason we get an init sequence with zero width/height,
|
||||
// which creates problems in the cairo layer. It tries to clear
|
||||
// the 'similar' surface it's creating, and with a zero width/height
|
||||
// it incorrectly thinks the clear failed...so we will init with
|
||||
// a minimum size of 1 for width/height...
|
||||
_surface = cairo_surface_create_similar(window, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
MAX(1, csize.width),
|
||||
MAX(1, csize.height));
|
||||
cairo_status_t status = cairo_surface_status(_surface);
|
||||
|
||||
// Check for error...
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
// Output the surface create error...
|
||||
NSWarnMLog(@"surface create FAILED - status: %s\n", cairo_status_to_string(status));
|
||||
|
||||
// Destroy the surface created...
|
||||
cairo_surface_destroy(_surface);
|
||||
|
||||
// And deallocate ourselves...
|
||||
DESTROY(self);
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the initial surface created...
|
||||
cairo_surface_destroy(window);
|
||||
|
||||
// Release the device context...
|
||||
ReleaseDC((HWND)device, hDC);
|
||||
}
|
||||
|
||||
if (win && self)
|
||||
{
|
||||
// We need this for handleExposeEvent in WIN32Server...
|
||||
win->surface = (void*)self;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
|
@ -1705,6 +1705,21 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
|
|||
|
||||
NSDebugLLog(@"WTrace", @"windowdevice: %d", winNum);
|
||||
window = GSWindowWithNumber(winNum);
|
||||
|
||||
/* FIXME:
|
||||
* The windows with autodisplay set to NO aren't displayed correctly on
|
||||
* Windows, no matter the backing store type used. And trying to redisplay
|
||||
* these windows here in the server not takes effect. So if the window
|
||||
* have set autodisplay to NO, we change it to YES before create the window.
|
||||
* This problem affects the tooltips, but this solution is different to
|
||||
* the one used in the TestPlant branch. Because that solution involves
|
||||
* changes in the side of GUI.
|
||||
*/
|
||||
if (![window isAutodisplay])
|
||||
{
|
||||
[window setAutodisplay: YES];
|
||||
}
|
||||
|
||||
GetClientRect((HWND)winNum, &rect);
|
||||
h = rect.bottom - rect.top;
|
||||
[self styleoffsets: &l : &r : &t : &b : [window styleMask]];
|
||||
|
|
Loading…
Reference in a new issue