* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
#include "config.h"
#include <stdlib.h>
+#include <windows.h>
#include "gdk.h"
#include "gdkwindowimpl.h"
static GSList *modal_window_stack = NULL;
static const cairo_user_data_key_t gdk_win32_cairo_key;
+typedef struct _FullscreenInfo FullscreenInfo;
+
+struct _FullscreenInfo
+{
+ RECT r;
+ guint hint_flags;
+ LONG style;
+};
static void update_style_bits (GdkWindow *window);
static gboolean _gdk_window_get_functions (GdkWindow *window,
GdkWMFunction *functions);
+static HDC _gdk_win32_impl_acquire_dc (GdkWindowImplWin32 *impl);
+static void _gdk_win32_impl_release_dc (GdkWindowImplWin32 *impl);
#define WINDOW_IS_TOPLEVEL(window) \
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
impl->hicon_small = NULL;
impl->hint_flags = 0;
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
- impl->extension_events_selected = FALSE;
impl->transient_owner = NULL;
impl->transient_children = NULL;
impl->num_transients = 0;
* Create native windows.
*
* With the default Gdk the created windows are mostly toplevel windows.
- * A lot of child windows are only created for GDK_NATIVE_WINDOWS.
*
* Placement of the window is derived from the passed in window,
* except for toplevel window where OS/Window Manager placement
GdkWindowImplWin32 *impl;
const gchar *title;
wchar_t *wtitle;
+ gboolean override_redirect;
gint window_width, window_height;
gint offset_x = 0, offset_y = 0;
- gint x, y;
+ gint x, y, real_x = 0, real_y = 0;
/* check consistency of redundant information */
guint remaining_mask = attributes_mask;
g_assert (attributes->y == window->y);
remaining_mask &= ~GDK_WA_Y;
}
+ override_redirect = FALSE;
if ((attributes_mask & GDK_WA_NOREDIR) != 0)
- remaining_mask &= ~GDK_WA_NOREDIR;
+ {
+ override_redirect = !!attributes->override_redirect;
+ remaining_mask &= ~GDK_WA_NOREDIR;
+ }
if ((remaining_mask & ~(GDK_WA_WMCLASS|GDK_WA_VISUAL|GDK_WA_CURSOR|GDK_WA_TITLE|GDK_WA_TYPE_HINT)) != 0)
g_warning ("_gdk_window_impl_new: uexpected attribute 0x%X",
if (attributes_mask & GDK_WA_VISUAL)
g_assert (gdk_screen_get_system_visual (screen) == attributes->visual);
- impl->extension_events_selected = FALSE;
+ impl->override_redirect = override_redirect;
/* wclass is not any longer set always, but if is ... */
if ((attributes_mask & GDK_WA_WMCLASS) == GDK_WA_WMCLASS)
/* A temp window is not necessarily a top level window */
dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
- dwExStyle |= WS_EX_TOOLWINDOW;
+ dwExStyle |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
offset_x = _gdk_offset_x;
offset_y = _gdk_offset_y;
break;
AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
- /* non child windows are placed by the OS/window manager */
- x = y = CW_USEDEFAULT;
+ real_x = window->x - offset_x;
+ real_y = window->y - offset_y;
+
+ if (window->window_type == GDK_WINDOW_TOPLEVEL)
+ {
+ /* We initially place it at default so that we can get the
+ default window positioning if we want */
+ x = y = CW_USEDEFAULT;
+ }
+ else
+ {
+ /* TEMP, FOREIGN: Put these where requested */
+ x = real_x;
+ y = real_y;
+ }
window_width = rect.right - rect.left;
window_height = rect.bottom - rect.top;
if (!title || !*title)
title = "";
- window->event_mask = GDK_STRUCTURE_MASK | event_mask;
+ impl->native_event_mask = GDK_STRUCTURE_MASK | event_mask;
if (attributes_mask & GDK_WA_TYPE_HINT)
gdk_window_set_type_hint (window, attributes->type_hint);
}
+ if (window->window_type != GDK_WINDOW_CHILD)
+ {
+ GetWindowRect (GDK_WINDOW_HWND (window), &rect);
+ impl->initial_x = rect.left;
+ impl->initial_y = rect.top;
+
+ /* Now we know the initial position, move to actually specified position */
+ if (real_x != x || real_y != y)
+ {
+ API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
+ real_x, real_y, 0, 0,
+ SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
+ }
+ }
+
g_object_ref (window);
gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
window->destroyed = TRUE;
DestroyWindow (GDK_WINDOW_HWND (window));
}
-
- gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
}
static cairo_surface_t *
if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
{
+#ifdef G_ENABLE_DEBUG
gint orig_x = *x, orig_y = *y;
+#endif
switch (impl->hints.win_gravity)
{
static void
show_window_internal (GdkWindow *window,
- gboolean raise,
+ gboolean already_mapped,
gboolean deiconify)
{
- HWND old_active_window;
- gboolean focus_on_map = TRUE;
+ GdkWindowImplWin32 *window_impl;
+ gboolean focus_on_map = FALSE;
DWORD exstyle;
- HWND top;
if (window->destroyed)
return;
- GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
+ GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s\n",
GDK_WINDOW_HWND (window),
_gdk_win32_window_state_to_string (window->state),
- (raise ? " raise" : ""),
(deiconify ? " deiconify" : "")));
/* If asked to show (not deiconify) an withdrawn and iconified
* window, do that.
*/
if (!deiconify &&
- !GDK_WINDOW_IS_MAPPED (window) &&
+ !already_mapped &&
(window->state & GDK_WINDOW_STATE_ICONIFIED))
{
- ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
+ ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMINNOACTIVE);
return;
}
/* If asked to show (but not raise) a window that is already
* visible, do nothing.
*/
- if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
+ if (!deiconify && !already_mapped && IsWindowVisible (GDK_WINDOW_HWND (window)))
return;
/* Other cases */
- if (!GDK_WINDOW_IS_MAPPED (window))
- {
- gdk_synthesize_window_state (window,
- GDK_WINDOW_STATE_WITHDRAWN,
- 0);
- focus_on_map = window->focus_on_map;
- }
+ if (!already_mapped)
+ focus_on_map = window->focus_on_map;
exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
- if (window->state & GDK_WINDOW_STATE_BELOW)
- exstyle &= (~WS_EX_TOPMOST);
-
- if (window->state & GDK_WINDOW_STATE_ABOVE)
- exstyle |= WS_EX_TOPMOST;
-
- if (exstyle & WS_EX_TOPMOST)
- top = HWND_TOPMOST;
- else
- top = HWND_TOP;
-
/* Use SetWindowPos to show transparent windows so automatic redraws
* in other windows can be suppressed.
*/
if (exstyle & WS_EX_TRANSPARENT)
{
- UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
+ UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
- if (!raise)
- flags |= SWP_NOZORDER;
- if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
+ if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
flags |= SWP_NOACTIVATE;
- SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
+ SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0, flags);
return;
}
- old_active_window = GetActiveWindow ();
+ /* For initial map of "normal" windows we want to emulate WM window
+ * positioning behaviour, which means:
+ * + Use user specified position if GDK_HINT_POS or GDK_HINT_USER_POS
+ * otherwise:
+ * + default to the initial CW_USEDEFAULT placement,
+ * no matter if the user moved the window before showing it.
+ * + Certain window types and hints have more elaborate positioning
+ * schemes.
+ */
+ window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+ if (!already_mapped &&
+ GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL &&
+ (window_impl->hint_flags & (GDK_HINT_POS | GDK_HINT_USER_POS)) == 0 &&
+ !window_impl->override_redirect)
+ {
+ gboolean center = FALSE;
+ RECT window_rect, center_on_rect;
+ int x, y;
+
+ x = window_impl->initial_x;
+ y = window_impl->initial_y;
+
+ if (window_impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
+ {
+ HMONITOR monitor;
+ MONITORINFO mi;
+
+ monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
+ mi.cbSize = sizeof (mi);
+ if (monitor && GetMonitorInfo (monitor, &mi))
+ center_on_rect = mi.rcMonitor;
+ else
+ {
+ center_on_rect.left = 0;
+ center_on_rect.right = 0;
+ center_on_rect.right = GetSystemMetrics (SM_CXSCREEN);
+ center_on_rect.bottom = GetSystemMetrics (SM_CYSCREEN);
+ }
+ center = TRUE;
+ }
+ else if (window_impl->transient_owner != NULL &&
+ GDK_WINDOW_IS_MAPPED (window_impl->transient_owner))
+ {
+ GdkWindow *owner = window_impl->transient_owner;
+ /* Center on transient parent */
+ center_on_rect.left = owner->x;
+ center_on_rect.top = owner->y;
+ center_on_rect.right = center_on_rect.left + owner->width;
+ center_on_rect.bottom = center_on_rect.top + owner->height;
+ _gdk_win32_adjust_client_rect (GDK_WINDOW (owner), ¢er_on_rect);
+ center = TRUE;
+ }
+
+ if (center)
+ {
+ window_rect.left = 0;
+ window_rect.top = 0;
+ window_rect.right = window->width;
+ window_rect.bottom = window->height;
+ _gdk_win32_adjust_client_rect (window, &window_rect);
+
+ x = center_on_rect.left + ((center_on_rect.right - center_on_rect.left) - (window_rect.right - window_rect.left)) / 2;
+ y = center_on_rect.top + ((center_on_rect.bottom - center_on_rect.top) - (window_rect.bottom - window_rect.top)) / 2;
+ }
+
+ API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
+ x, y, 0, 0,
+ SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
+ }
+
+ if (!already_mapped &&
+ GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL &&
+ !window_impl->override_redirect)
+ {
+ /* Ensure new windows are fully onscreen */
+ RECT window_rect;
+ HMONITOR monitor;
+ MONITORINFO mi;
+ int x, y;
+
+ GetWindowRect (GDK_WINDOW_HWND (window), &window_rect);
+
+ monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
+ mi.cbSize = sizeof (mi);
+ if (monitor && GetMonitorInfo (monitor, &mi))
+ {
+ x = window_rect.left;
+ y = window_rect.top;
+
+ if (window_rect.right > mi.rcWork.right)
+ {
+ window_rect.left -= (window_rect.right - mi.rcWork.right);
+ window_rect.right -= (window_rect.right - mi.rcWork.right);
+ }
+
+ if (window_rect.bottom > mi.rcWork.bottom)
+ {
+ window_rect.top -= (window_rect.bottom - mi.rcWork.bottom);
+ window_rect.bottom -= (window_rect.bottom - mi.rcWork.bottom);
+ }
+
+ if (window_rect.left < mi.rcWork.left)
+ {
+ window_rect.right += (mi.rcWork.left - window_rect.left);
+ window_rect.left += (mi.rcWork.left - window_rect.left);
+ }
+
+ if (window_rect.top < mi.rcWork.top)
+ {
+ window_rect.bottom += (mi.rcWork.top - window_rect.top);
+ window_rect.top += (mi.rcWork.top - window_rect.top);
+ }
+
+ if (x != window_rect.left || y != window_rect.top)
+ API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
+ window_rect.left, window_rect.top, 0, 0,
+ SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
+ }
+ }
+
if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
{
}
else if (window->state & GDK_WINDOW_STATE_ICONIFIED)
{
- ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
+ if (focus_on_map)
+ ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
+ else
+ ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
}
else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
{
ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
}
- if (raise)
- {
- if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
- SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
- 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
- else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
- {
- if (focus_on_map && window->accept_focus)
- {
- SetForegroundWindow (GDK_WINDOW_HWND (window));
- if (top == HWND_TOPMOST)
- SetWindowPos (GDK_WINDOW_HWND (window), top,
- 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
- }
- else
- {
- SetWindowPos (GDK_WINDOW_HWND (window), top,
- 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
- }
- }
- else
- {
- BringWindowToTop (GDK_WINDOW_HWND (window));
- }
- }
- else if (old_active_window != GDK_WINDOW_HWND (window))
+ /* Sync STATE_ABOVE to TOPMOST */
+ if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_TEMP &&
+ (((window->state & GDK_WINDOW_STATE_ABOVE) &&
+ !(exstyle & WS_EX_TOPMOST)) ||
+ (!(window->state & GDK_WINDOW_STATE_ABOVE) &&
+ (exstyle & WS_EX_TOPMOST))))
{
- SetActiveWindow (old_active_window);
+ API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
+ (window->state & GDK_WINDOW_STATE_ABOVE)?HWND_TOPMOST:HWND_NOTOPMOST,
+ 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
}
}
gint width,
gint height)
{
+ GdkWindowImplWin32 *window_impl;
+
+ window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+ window_impl->inhibit_configure = TRUE;
+
+ /* We ignore changes to the window being moved or resized by the
+ user, as we don't want to fight the user */
+ if (GDK_WINDOW_HWND (window) == _modal_move_resize_window)
+ goto out;
+
if (with_move && (width < 0 && height < 0))
{
gdk_win32_window_move (window, x, y);
gdk_win32_window_resize (window, width, height);
}
}
+
+ out:
+ window_impl->inhibit_configure = FALSE;
+
+ if (WINDOW_IS_TOPLEVEL (window))
+ _gdk_win32_emit_configure_event (window);
}
static gboolean
0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
else if (window->accept_focus)
- API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
+ /* Do not wrap this in an API_CALL macro as SetForegroundWindow might
+ * fail when for example dragging a window belonging to a different
+ * application at the time of a gtk_window_present() call due to focus
+ * stealing prevention. */
+ SetForegroundWindow (GDK_WINDOW_HWND (window));
else
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
0, 0, 0, 0,
gboolean urgent)
{
FLASHWINFO flashwinfo;
- typedef BOOL (*PFN_FlashWindowEx) (FLASHWINFO*);
+ typedef BOOL (WINAPI *PFN_FlashWindowEx) (FLASHWINFO*);
PFN_FlashWindowEx flashWindowEx = NULL;
g_return_if_fail (GDK_IS_WINDOW (window));
GdkWindowHints geom_mask)
{
GdkWindowImplWin32 *impl;
+ FullscreenInfo *fi;
g_return_if_fail (GDK_IS_WINDOW (window));
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
- impl->hint_flags = geom_mask;
+ fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
+ if (fi)
+ fi->hint_flags = geom_mask;
+ else
+ impl->hint_flags = geom_mask;
impl->hints = *geometry;
if (geom_mask & GDK_HINT_POS)
}
}
-GdkWindow *
-_gdk_modal_current (void)
+gboolean
+_gdk_modal_blocked (GdkWindow *window)
{
- if (modal_window_stack != NULL)
+ GSList *l;
+ gboolean found_any = FALSE;
+
+ for (l = modal_window_stack; l != NULL; l = l->next)
{
- GSList *tmp = modal_window_stack;
+ GdkWindow *modal = l->data;
- while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (GDK_WINDOW (tmp->data)))
- {
- tmp = g_slist_next (tmp);
- }
+ if (modal == window)
+ return FALSE;
- return tmp != NULL ? tmp->data : NULL;
+ if (GDK_WINDOW_IS_MAPPED (modal))
+ found_any = TRUE;
}
- else
+
+ return found_any;
+}
+
+GdkWindow *
+_gdk_modal_current (void)
+{
+ GSList *l;
+
+ for (l = modal_window_stack; l != NULL; l = l->next)
{
- return NULL;
+ GdkWindow *modal = l->data;
+
+ if (GDK_WINDOW_IS_MAPPED (modal))
+ return modal;
}
+
+ return NULL;
}
static void
static GdkEventMask
gdk_win32_window_get_events (GdkWindow *window)
{
+ GdkWindowImplWin32 *impl;
+
if (GDK_WINDOW_DESTROYED (window))
return 0;
- return window->event_mask;
+ impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+ return impl->native_event_mask;
}
static void
gdk_win32_window_set_events (GdkWindow *window,
- GdkEventMask event_mask)
+ GdkEventMask event_mask)
{
+ GdkWindowImplWin32 *impl;
+
+ impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
/* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
* set it here, too. Not that I know or remember why it is
* necessary, will have to test some day.
*/
- window->event_mask = GDK_STRUCTURE_MASK | event_mask;
+ impl->native_event_mask = GDK_STRUCTURE_MASK | event_mask;
}
static void
gdk_win32_window_set_override_redirect (GdkWindow *window,
gboolean override_redirect)
{
+ GdkWindowImplWin32 *window_impl;
+
g_return_if_fail (GDK_IS_WINDOW (window));
- g_warning ("gdk_window_set_override_redirect not implemented");
+ window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+ window_impl->override_redirect = !!override_redirect;
}
static void
gboolean all;
RECT rect, before, after;
+ if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
+ return;
+
old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
new_style = old_style;
new_exstyle = old_exstyle;
- if (window->window_type == GDK_WINDOW_TEMP ||
- impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
- new_exstyle |= WS_EX_TOOLWINDOW;
+ if (window->window_type == GDK_WINDOW_TEMP)
+ new_exstyle |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
+ else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
+ new_exstyle |= WS_EX_TOOLWINDOW ;
else
new_exstyle &= ~WS_EX_TOOLWINDOW;
_gdk_window_get_functions (GdkWindow *window,
GdkWMFunction *functions)
{
- GdkWMDecoration* functions_set;
+ GdkWMFunction* functions_set;
functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
if (functions_set)
static void
gdk_win32_window_begin_resize_drag (GdkWindow *window,
GdkWindowEdge edge,
+ GdkDevice *device,
gint button,
gint root_x,
gint root_y,
static void
gdk_win32_window_begin_move_drag (GdkWindow *window,
+ GdkDevice *device,
gint button,
gint root_x,
gint root_y,
if (GDK_WINDOW_IS_MAPPED (window))
{
- show_window_internal (window, FALSE, TRUE);
+ show_window_internal (window, GDK_WINDOW_IS_MAPPED (window), TRUE);
}
else
{
0);
}
-typedef struct _FullscreenInfo FullscreenInfo;
-
-struct _FullscreenInfo
-{
- RECT r;
- guint hint_flags;
- LONG style;
-};
-
static void
gdk_win32_window_fullscreen (GdkWindow *window)
{
g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
+ /* Send state change before configure event */
+ gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
+
SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
(fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
x, y, width, height,
SWP_NOCOPYBITS | SWP_SHOWWINDOW));
-
- gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
}
}
{
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+ gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
+
impl->hint_flags = fi->hint_flags;
SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
g_free (fi);
-
- gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
+ update_style_bits (window);
}
}
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
}
- else
- gdk_synthesize_window_state (window,
- setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
- setting ? GDK_WINDOW_STATE_ABOVE : 0);
+
+ gdk_synthesize_window_state (window,
+ setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
+ setting ? GDK_WINDOW_STATE_ABOVE : 0);
}
static void
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
}
- else
- gdk_synthesize_window_state (window,
- setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
- setting ? GDK_WINDOW_STATE_BELOW : 0);
+
+ gdk_synthesize_window_state (window,
+ setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
+ setting ? GDK_WINDOW_STATE_BELOW : 0);
}
static void
return (GdkWindow*) gdk_win32_handle_table_lookup (anid);
}
-static void
-gdk_win32_window_enable_synchronized_configure (GdkWindow *window)
-{
- /* nothing - no window manager to cooperate with */
-}
-
-static void
-gdk_win32_window_configure_finished (GdkWindow *window)
-{
- /* nothing - no window manager to cooperate with */
-}
-
static void
gdk_win32_window_set_opacity (GdkWindow *window,
gdouble opacity)
{
LONG exstyle;
- typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
+ typedef BOOL (WINAPI *PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
g_return_if_fail (GDK_IS_WINDOW (window));
exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
if (!(exstyle & WS_EX_LAYERED))
- API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
- GWL_EXSTYLE,
- exstyle | WS_EX_LAYERED));
+ SetWindowLong (GDK_WINDOW_HWND (window),
+ GWL_EXSTYLE,
+ exstyle | WS_EX_LAYERED);
setLayeredWindowAttributes =
(PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
gint dx,
gint dy)
{
+ GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
GdkRectangle extents;
RECT rect;
+ HRGN hrgn, area_hrgn;
+ HDC hdc;
+ int ret;
+
+ /* Note: This is the destination area, not the source, and
+ it has been moved by dx, dy from the source area */
+ area_hrgn = cairo_region_to_hrgn (area, 0, 0);
+
+ /* First we copy any outstanding invalid areas in the
+ source area to the new position in the destination area */
+ hrgn = CreateRectRgn (0, 0, 0, 0);
+ ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
+ if (ret == ERROR)
+ WIN32_API_FAILED ("GetUpdateRgn");
+ else if (ret != NULLREGION)
+ {
+ /* Convert the source invalid region as it would be copied */
+ OffsetRgn (hrgn, dx, dy);
+ /* Keep what intersects the copy destination area */
+ ret = CombineRgn (hrgn, hrgn, area_hrgn, RGN_AND);
+ /* And invalidate it */
+ if (ret == ERROR)
+ WIN32_API_FAILED ("CombineRgn");
+ else if (ret != NULLREGION)
+ API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), hrgn, TRUE));
+ }
+
+ /* Then we copy the bits, invalidating whatever is copied from
+ otherwise invisible areas */
+
+ hdc = _gdk_win32_impl_acquire_dc (impl);
+
+ /* Clip hdc to target region */
+ API_CALL (SelectClipRgn, (hdc, area_hrgn));
cairo_region_get_extents (area, &extents);
- rect.left = extents.x - dx;
- rect.top = extents.y - dy;
- rect.right = rect.left + extents.width;
- rect.bottom = rect.top + extents.height;
- API_CALL (ScrollWindowEx, (GDK_WINDOW_HWND (window),
- dx, dy, &rect,
- NULL, NULL, NULL,
- SW_INVALIDATE));
+ rect.left = MIN (extents.x, extents.x - dx);
+ rect.top = MIN (extents.y, extents.y - dy);
+ rect.right = MAX (extents.x + extents.width, extents.x - dx + extents.width);
+ rect.bottom = MAX (extents.y + extents.height, extents.y - dy + extents.height);
+
+ SetRectRgn (hrgn, 0, 0, 0, 0);
+ if (!ScrollDC (hdc, dx, dy, &rect, NULL, hrgn, NULL))
+ WIN32_GDI_FAILED ("ScrollDC");
+ else if (!InvalidateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE))
+ WIN32_GDI_FAILED ("InvalidateRgn");
+
+ /* Unset hdc clip region */
+ API_CALL (SelectClipRgn, (hdc, NULL));
+
+ _gdk_win32_impl_release_dc (impl);
+
+ if (!DeleteObject (hrgn))
+ WIN32_GDI_FAILED ("DeleteObject");
+
+ if (!DeleteObject (area_hrgn))
+ WIN32_GDI_FAILED ("DeleteObject");
}
static void
}
}
+HWND
+gdk_win32_window_get_impl_hwnd (GdkWindow *window)
+{
+ if (GDK_WINDOW_IS_WIN32 (window))
+ return GDK_WINDOW_HWND (window);
+ return NULL;
+}
+
static void
gdk_win32_cairo_surface_destroy (void *data)
{
impl_class->begin_resize_drag = gdk_win32_window_begin_resize_drag;
impl_class->begin_move_drag = gdk_win32_window_begin_move_drag;
- impl_class->enable_synchronized_configure = gdk_win32_window_enable_synchronized_configure;
- impl_class->configure_finished = gdk_win32_window_configure_finished;
impl_class->set_opacity = gdk_win32_window_set_opacity;
//impl_class->set_composited = gdk_win32_window_set_composited;
impl_class->destroy_notify = gdk_win32_window_destroy_notify;
HGDIOBJ
gdk_win32_window_get_handle (GdkWindow *window)
{
+ /* Try to ensure the window has a native window */
+ if (!_gdk_window_has_impl (window))
+ gdk_window_ensure_native (window);
+
+ if (!GDK_WINDOW_IS_WIN32 (window))
+ {
+ g_warning (G_STRLOC " window is not a native Win32 window");
+ return NULL;
+ }
+
return GDK_WINDOW_HWND (window);
}