* 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 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;
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 ... */
/* 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;
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)
{
gboolean deiconify)
{
GdkWindowImplWin32 *window_impl;
- HWND old_active_window;
gboolean focus_on_map = FALSE;
DWORD exstyle;
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)
{
gdk_window_fullscreen (window);
}
/* Sync STATE_ABOVE to TOPMOST */
- if (((window->state & GDK_WINDOW_STATE_ABOVE) &&
- !(exstyle & WS_EX_TOPMOST)) ||
- (!(window->state & GDK_WINDOW_STATE_ABOVE) &&
- (exstyle & WS_EX_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))))
{
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
(window->state & GDK_WINDOW_STATE_ABOVE)?HWND_TOPMOST:HWND_NOTOPMOST,
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));
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;
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));
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
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;