Hello community,

here is the log from the commit of package wlc for openSUSE:Factory checked in 
at 2016-08-20 12:27:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/wlc (Old)
 and      /work/SRC/openSUSE:Factory/.wlc.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "wlc"

Changes:
--------
--- /work/SRC/openSUSE:Factory/wlc/wlc.changes  2016-06-02 09:38:37.000000000 
+0200
+++ /work/SRC/openSUSE:Factory/.wlc.new/wlc.changes     2016-08-20 
12:27:16.000000000 +0200
@@ -2 +2,22 @@
-Mon May 30 18:25:56 UTC 2016 - tc...@suse.com
+Tue Aug  2 20:05:32 UTC 2016 - sleep_wal...@opensuse.org
+
+- bump to 0.0.5
+   implement wlc_view_get_pid()
+   xwm: do not try to focus override_redirect windows
+   keyboard: Send focus out only on way<->x11 change
+   view: Return visible geo as input area for x views
+
+-------------------------------------------------------------------
+Sun Jul 31 12:41:23 UTC 2016 - sleep_wal...@opensuse.org
+
+- bump to 0.0.4
+   Bump version to 0.0.4
+    HiDPI, surface and subsurface related features and fixes
+    s/wlc_resource/wlc_handle/
+    Remove spammy debug log.
+    add WLC_DRAW_INPUT env var
+    xwm features
+    (for complete list of changes check git log)
+
+-------------------------------------------------------------------
+Mon May 30 18:25:56 UTC 2016 - sleep_wal...@opensuse.org
@@ -7 +28 @@
-Mon May 23 10:02:13 UTC 2016 - tc...@suse.com
+Mon May 23 10:02:13 UTC 2016 - sleep_wal...@opensuse.org
@@ -16 +37 @@
-Thu May  5 12:50:48 UTC 2016 - tc...@suse.com
+Thu May  5 12:50:48 UTC 2016 - sleep_wal...@opensuse.org
@@ -28 +49 @@
-Fri Apr 15 19:19:04 UTC 2016 - tc...@suse.com
+Fri Apr 15 19:19:04 UTC 2016 - sleep_wal...@opensuse.org

Old:
----
  wlc-0.0.3.tar.bz2
  wlc-0.0.3.tar.bz2.asc

New:
----
  wlc-0.0.5.tar.bz2
  wlc-0.0.5.tar.bz2.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ wlc.spec ++++++
--- /var/tmp/diff_new_pack.pDWImx/_old  2016-08-20 12:27:17.000000000 +0200
+++ /var/tmp/diff_new_pack.pDWImx/_new  2016-08-20 12:27:17.000000000 +0200
@@ -19,7 +19,7 @@
 %define wayland_minimal 1.7.0
 
 Name:           wlc
-Version:        0.0.3
+Version:        0.0.5
 Release:        0
 Summary:        A Wayland Compositor Library
 License:        MIT

++++++ wlc-0.0.3.tar.bz2 -> wlc-0.0.5.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/CMakeLists.txt new/wlc-0.0.5/CMakeLists.txt
--- old/wlc-0.0.3/CMakeLists.txt        2016-05-22 21:15:27.000000000 +0200
+++ new/wlc-0.0.5/CMakeLists.txt        2016-08-02 19:57:11.000000000 +0200
@@ -1,5 +1,5 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
-PROJECT(wlc VERSION 0.0.3 LANGUAGES C)
+PROJECT(wlc VERSION 0.0.5 LANGUAGES C)
 set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${PROJECT_SOURCE_DIR}/CMake")
 
 # Subprojects
@@ -83,7 +83,7 @@
 create_custom_linker_flags(Upstream ${ldflags})
 create_custom_compiler_flags(Upstream -g -O2 ${cflags})
 
-add_compiler_warnings(-Wall -Wextra -Wno-variadic-macros -Wno-long-long 
-Wformat=2 -Winit-self -Wfloat-equal -Wcast-align -Wpointer-arith 
-Wmissing-prototypes)
+add_compiler_warnings(-Wall -Wextra -Wno-variadic-macros -Wno-long-long 
-Wformat=2 -Winit-self -Wfloat-equal -Wcast-align -Wpointer-arith 
-Wmissing-prototypes -Wno-nonnull-compare)
 
 if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
    add_compiler_warnings(-Wsuggest-attribute=pure -Wsuggest-attribute=const)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/example/example.c 
new/wlc-0.0.5/example/example.c
--- old/wlc-0.0.3/example/example.c     2016-05-22 21:15:27.000000000 +0200
+++ new/wlc-0.0.5/example/example.c     2016-08-02 19:57:11.000000000 +0200
@@ -73,7 +73,7 @@
    // you probably don't want to layout certain type of windows in wm
 
    const struct wlc_size *r;
-   if (!(r = wlc_output_get_resolution(output)))
+   if (!(r = wlc_output_get_virtual_resolution(output)))
       return;
 
    size_t memb;
@@ -81,11 +81,22 @@
 
    bool toggle = false;
    uint32_t y = 0;
-   uint32_t w = r->w / 2, h = r->h / chck_maxu32((1 + memb) / 2, 1);
+   const uint32_t n = chck_maxu32((1 + memb) / 2, 1);
+   const uint32_t w = r->w / 2, h = r->h / n;
+   const uint32_t ew = r->w - w * 2, eh = r->h - h * n;
    for (size_t i = 0; i < memb; ++i) {
-      struct wlc_geometry g = { { (toggle ? w : 0), y }, { (!toggle && i == 
memb - 1 ? r->w : w), h } };
+      const struct wlc_geometry g = {
+         .origin = {
+            .x = (toggle ? w + ew : 0),
+            .y =  y
+         },
+         .size = {
+            .w = (!toggle && i == memb - 1 ? r->w : (toggle ? w : w + ew)),
+            .h = (i < 2 ? h + eh : h)
+         }
+      };
       wlc_view_set_geometry(views[i], 0, &g);
-      y = y + (!(toggle = !toggle) ? h : 0);
+      y = y + (!(toggle = !toggle) ? g.size.h : 0);
    }
 }
 
@@ -163,6 +174,16 @@
          char *terminal = (getenv("TERMINAL") ? getenv("TERMINAL") : 
"weston-terminal");
          wlc_exec(terminal, (char *const[]){ terminal, NULL });
          return true;
+      } else if (modifiers->mods & WLC_BIT_MOD_CTRL && sym >= XKB_KEY_1 && sym 
<= XKB_KEY_9) {
+         size_t memb;
+         const wlc_handle *outputs = wlc_get_outputs(&memb);
+         const uint32_t scale = (sym - XKB_KEY_1) + 1;
+
+         for (size_t i = 0; i < memb; ++i)
+            wlc_output_set_resolution(outputs[i], 
wlc_output_get_resolution(outputs[i]), scale);
+
+         printf("scale: %u\n", scale);
+         return true;
       }
    }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/include/wlc/wlc.h 
new/wlc-0.0.5/include/wlc/wlc.h
--- old/wlc-0.0.3/include/wlc/wlc.h     2016-05-22 21:15:27.000000000 +0200
+++ new/wlc-0.0.5/include/wlc/wlc.h     2016-08-02 19:57:11.000000000 +0200
@@ -8,6 +8,7 @@
 #include <wlc/defines.h>
 #include <wlc/geometry.h>
 #include <xkbcommon/xkbcommon-keysyms.h>
+#include <sys/types.h>
 
 struct wlc_event_source;
 
@@ -61,6 +62,7 @@
    WLC_BIT_PROPERTY_TITLE = 1<<0,
    WLC_BIT_PROPERTY_CLASS = 1<<1,
    WLC_BIT_PROPERTY_APP_ID = 1<<2,
+   WLC_BIT_PROPERTY_PID = 1<<3,
 };
 
 /** wlc_view_set_geometry(); Edges in interface interface.view.request.resize 
function. */
@@ -278,11 +280,25 @@
 /** Wake up / sleep. */
 void wlc_output_set_sleep(wlc_handle output, bool sleep);
 
-/** Get resolution. */
+/**
+ * Get real resolution.
+ * Resolution applied by either wlc_output_set_resolution call or initially.
+ * Do not use this for coordinate boundary.
+ */
 const struct wlc_size* wlc_output_get_resolution(wlc_handle output);
 
+/**
+ * Get virtual resolution.
+ * Resolution with transformations applied for proper rendering for example on 
high density displays.
+ * Use this to figure out coordinate boundary.
+ */
+const struct wlc_size* wlc_output_get_virtual_resolution(wlc_handle output);
+
 /** Set resolution. */
-WLC_NONULL void wlc_output_set_resolution(wlc_handle output, const struct 
wlc_size *resolution);
+WLC_NONULL void wlc_output_set_resolution(wlc_handle output, const struct 
wlc_size *resolution, uint32_t scale);
+
+/** Get scale factor. */
+uint32_t wlc_output_get_scale(wlc_handle output);
 
 /** Get current visibility bitmask. */
 uint32_t wlc_output_get_mask(wlc_handle output);
@@ -374,6 +390,9 @@
 /** Get app id. (xdg-surface only) */
 const char* wlc_view_get_app_id(wlc_handle view);
 
+/** Get pid. */
+pid_t wlc_view_get_pid(wlc_handle view);
+
 /** --  Input API
  * Very recent stuff, things may change.
  * XXX: This api is dumb and assumes there is only single xkb state and keymap.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/man/man3/wlc_view_get_pid.3 
new/wlc-0.0.5/man/man3/wlc_view_get_pid.3
--- old/wlc-0.0.3/man/man3/wlc_view_get_pid.3   1970-01-01 01:00:00.000000000 
+0100
+++ new/wlc-0.0.5/man/man3/wlc_view_get_pid.3   2016-08-02 19:57:11.000000000 
+0200
@@ -0,0 +1,32 @@
+.TH WLC_VIEW_GET_PID 3 2016-07-29 WLC "WLC Core API Functions"
+
+.SH NAME
+wlc_view_get_pid - get the process id for a given view
+
+.SH SYNOPSIS
+.B #include <wlc/wlc.h>
+
+.BI "pid_t wlc_view_get_pid(wlc_handle "view ");"
+
+.SS Wayland protocol requirements:
+.RS
+.BR wlc_view_get_pid ():
+xdg_shell
+.RE
+
+.SH DESCRIPTION
+.BR wlc_view_get_pid ()
+can be used to acquire the process id of a given
+.I view.
+
+.SH RETURN VALUE
+.BR wlc_view_get_pid ()
+returns the process id for
+.I view
+if it is available. Returns 0 (not a valid pid) if it is not. For X11
+views this requires the application set the __NET_WM_PID property.
+
+.SH ALSO SEE
+The XDG Shell protocol extension
+.UR http://cgit.freedesktop.org/wayland/weston/tree/protocol/xdg-shell.xml
+.UE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/compositor/output.c 
new/wlc-0.0.5/src/compositor/output.c
--- old/wlc-0.0.3/src/compositor/output.c       2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/compositor/output.c       2016-08-02 19:57:11.000000000 
+0200
@@ -87,9 +87,10 @@
                            (output->information.model.data ? 
output->information.model.data : "model"),
                            output->information.transform);
 
-   assert(output->information.scale > 0);
-   if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
-      wl_output_send_scale(resource, output->information.scale);
+   if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) {
+      assert(output->scale > 0);
+      wl_output_send_scale(resource, output->scale);
+   }
 
    struct wlc_output_mode *mode;
    chck_iter_pool_for_each(&output->information.modes, mode) {
@@ -149,7 +150,7 @@
          visible = true;
 
          if (!should_blit)
-            return true;
+            break;
       }
 
       if (should_blit)
@@ -164,7 +165,7 @@
 {
    assert(output && output->blit);
 
-   const size_t gsz = output->resolution.w * output->resolution.h;
+   const size_t gsz = output->virtual.w * output->virtual.h;
    memset(output->blit, false, gsz);
 
    wlc_handle *h;
@@ -175,6 +176,7 @@
           !(s = convert_from_wlc_resource(v->surface, "surface")))
          continue;
 
+      wlc_view_commit_state(v, &v->pending, &v->commit);
       const bool vis = view_visible(v, s, output->active.mask);
 
       // This place sucks for this, but otherwise we would need API level 
interaction.
@@ -196,16 +198,17 @@
       struct wlc_geometry o;
       struct wlc_point a, b;
       const bool should_blit = wlc_view_get_opaque(v, &o);
-      a.x = chck_clamp32(o.origin.x, 0, output->resolution.w);
-      a.y = chck_clamp32(o.origin.y, 0, output->resolution.h);
-      b.x = chck_clamp32((o.origin.x + o.size.w), 1, output->resolution.w);
-      b.y = chck_clamp32((o.origin.y + o.size.h), 1, output->resolution.h);
+      a.x = chck_clamp32(o.origin.x, 0, output->virtual.w);
+      a.y = chck_clamp32(o.origin.y, 0, output->virtual.h);
+      b.x = chck_clamp32((o.origin.x + o.size.w), 1, output->virtual.w);
+      b.y = chck_clamp32((o.origin.y + o.size.h), 1, output->virtual.h);
 
-      if (!blit(output->blit, &output->resolution, &a, &b, should_blit)) {
-         wlc_dlog(WLC_DBG_RENDER_LOOP, "%" PRIuWLC " is not visible", *h);
+      if (!blit(output->blit, &output->virtual, &a, &b, should_blit)) {
+         wlc_dlog(WLC_DBG_RENDER_LOOP, "%" PRIuWLC " is not visible 
(%d,%d+%d,%d %d,%d+%ux%u)", *h, a.x, a.y, b.x, b.y, o.origin.x, o.origin.y, 
o.size.w, o.size.h);
          continue;
       }
 
+      wlc_dlog(WLC_DBG_RENDER_LOOP, "%" PRIuWLC " is visible (%d,%d+%d,%d 
%d,%d+%ux%u)", *h, a.x, a.y, b.x, b.y, o.origin.x, o.origin.y, o.size.w, 
o.size.h);
       chck_iter_pool_push_front(visible, &v);
    }
 
@@ -236,10 +239,15 @@
 static void
 render_subsurface(struct wlc_output *output, struct wlc_surface *surface, 
struct wlc_point offset, struct wlc_coordinate_scale parent_scale)
 {
-   const struct wlc_geometry g = (struct wlc_geometry) {
-       .origin = {offset.x + parent_scale.w * 
(surface->commit.subsurface_position.x + surface->commit.offset.x),
-                  offset.y + parent_scale.h * 
(surface->commit.subsurface_position.y + surface->commit.offset.y)},
-       .size = surface->size
+   const struct wlc_geometry g = {
+      .origin = {
+         .x = offset.x + parent_scale.w * 
(surface->commit.subsurface_position.x + surface->commit.offset.x),
+         .y = offset.y + parent_scale.h * 
(surface->commit.subsurface_position.y + surface->commit.offset.y)
+      },
+      .size = {
+         .w = surface->size.w * parent_scale.w,
+         .h = surface->size.h * parent_scale.h
+      },
    };
    wlc_render_surface_paint(&output->render, &output->context, surface, &g);
 }
@@ -247,9 +255,9 @@
 static void
 subsurfaces_render(struct wlc_output *output, struct wlc_surface *surface, 
struct wlc_coordinate_scale parent_scale, struct chck_iter_pool *callbacks, 
struct wlc_point offset)
 {
-
    if (!surface)
        return;
+
    /* do not render view's main surface twice */
    if (surface->parent)
        render_subsurface(output, surface, offset, parent_scale);
@@ -259,8 +267,8 @@
        subsurfaces_render(output, convert_from_wlc_resource(*sub, "surface"), 
surface->coordinate_transform,
              callbacks,
              (struct wlc_point) {
-              offset.x + (surface->parent ? 0 : 
surface->commit.subsurface_position.x / parent_scale.w),
-              offset.y + (surface->parent ? 0 : 
surface->commit.subsurface_position.y / parent_scale.h)
+             offset.x + (surface->parent ? 0 : 
surface->commit.subsurface_position.x / parent_scale.w),
+             offset.y + (surface->parent ? 0 : 
surface->commit.subsurface_position.y / parent_scale.h)
              });
    }
 
@@ -282,7 +290,6 @@
    if (!(surface = convert_from_wlc_resource(view->surface, "surface")))
       return;
 
-   wlc_view_commit_state(view, &view->pending, &view->commit);
    WLC_INTERFACE_EMIT(view.render.pre, convert_to_wlc_handle(view));
    wlc_render_flush_fakefb(&output->render, &output->context);
    wlc_render_view_paint(&output->render, &output->context, view);
@@ -315,7 +322,7 @@
       return false;
    }
 
-   wlc_render_resolution(&output->render, &output->context, &output->mode, 
&output->resolution);
+   wlc_render_resolution(&output->render, &output->context, &output->mode, 
&output->virtual, output->scale);
 
    if (output->state.sleeping) {
       // fake sleep
@@ -643,7 +650,7 @@
       wlc_log(WLC_LOG_INFO, "%s Chose mode (%u) %dx%d", 
output->information.name.data, output->active.mode, mode->width, mode->height);
       output->mode = (struct wlc_size){ mode->width, mode->height };
       mode->flags |= WL_OUTPUT_MODE_CURRENT;
-      set_resolution = wlc_output_set_resolution_ptr(output, &output->mode);
+      set_resolution = wlc_output_set_resolution_ptr(output, &output->mode, 
output->scale);
    }
 
    if (!set_resolution)
@@ -741,24 +748,28 @@
 }
 
 bool
-wlc_output_set_resolution_ptr(struct wlc_output *output, const struct wlc_size 
*resolution)
+wlc_output_set_resolution_ptr(struct wlc_output *output, const struct wlc_size 
*resolution, uint32_t scale)
 {
    if (!output)
       return false;
 
-   assert(resolution && resolution->w != 0 && resolution->h != 0);
+   assert(resolution && resolution->w != 0 && resolution->h != 0 && scale != 
0);
 
-   if (resolution->w == 0 || resolution->h == 0) {
-      wlc_log(WLC_LOG_WARN, "Tried to set resolution of output %" PRIuWLC "to 
%ux%u", convert_to_wlc_handle(output), resolution->w, resolution->h);
+   if (resolution->w == 0 || resolution->h == 0 || scale == 0) {
+      wlc_log(WLC_LOG_WARN, "Tried to set resolution of output %" PRIuWLC "to 
%ux%u / %u", convert_to_wlc_handle(output), resolution->w, resolution->h, 
scale);
       return false;
    }
 
-   if (wlc_size_equals(resolution, &output->resolution))
+   if (output->scale == scale && wlc_size_equals(resolution, 
&output->resolution))
       return false;
 
+   struct wlc_size virtual = *resolution;
+   virtual.w /= scale;
+   virtual.h /= scale;
+
    size_t gsz;
-   if (chck_mul_ofsz(resolution->w, resolution->h, &gsz)) {
-      wlc_log(WLC_LOG_WARN, "Requested resolution %ux%u overflows when 
multiplied, ignoring resolution", resolution->w, resolution->h);
+   if (chck_mul_ofsz(virtual.w, virtual.h, &gsz)) {
+      wlc_log(WLC_LOG_WARN, "Requested resolution %ux%u (%ux%u) overflows when 
multiplied, ignoring resolution", resolution->w, resolution->h, virtual.w, 
virtual.h);
       return false;
    }
 
@@ -767,6 +778,8 @@
 
    struct wlc_size old = output->resolution;
    output->resolution = *resolution;
+   output->virtual = virtual;
+   output->scale = scale;
 
    output_push_to_resources(output);
    WLC_INTERFACE_EMIT(output.resolution, convert_to_wlc_handle(output), &old, 
&output->resolution);
@@ -868,10 +881,23 @@
    return get(convert_from_wlc_handle(output, "output"), offsetof(struct 
wlc_output, resolution));
 }
 
+WLC_API const struct wlc_size*
+wlc_output_get_virtual_resolution(wlc_handle output)
+{
+   return get(convert_from_wlc_handle(output, "output"), offsetof(struct 
wlc_output, virtual));
+}
+
 WLC_API void
-wlc_output_set_resolution(wlc_handle output, const struct wlc_size *resolution)
+wlc_output_set_resolution(wlc_handle output, const struct wlc_size 
*resolution, uint32_t scale)
+{
+   wlc_output_set_resolution_ptr(convert_from_wlc_handle(output, "output"), 
resolution, scale);
+}
+
+WLC_API uint32_t
+wlc_output_get_scale(wlc_handle output)
 {
-   wlc_output_set_resolution_ptr(convert_from_wlc_handle(output, "output"), 
resolution);
+   void *ptr = get(convert_from_wlc_handle(output, "output"), offsetof(struct 
wlc_output, scale));
+   return (ptr ? *(uint32_t*)ptr : 1);
 }
 
 WLC_API bool
@@ -997,6 +1023,7 @@
 
    output->active.mode = UINT_MAX;
    output->state.ims = 41;
+   output->scale = 1;
 
    wlc_output_set_sleep_ptr(output, false);
    wlc_output_set_mask_ptr(output, (1<<0));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/compositor/output.h 
new/wlc-0.0.5/src/compositor/output.h
--- old/wlc-0.0.3/src/compositor/output.h       2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/compositor/output.h       2016-08-02 19:57:11.000000000 
+0200
@@ -33,7 +33,6 @@
    int32_t x, y;
    int32_t physical_width, physical_height;
    int32_t subpixel;
-   int32_t scale;
    uint32_t connector_id;
    enum wl_output_transform transform;
    enum wlc_connector_type connector;
@@ -41,7 +40,7 @@
 
 struct wlc_output {
    struct wlc_source resources;
-   struct wlc_size mode, resolution;
+   struct wlc_size mode, resolution, virtual;
    struct wlc_output_information information;
    struct wlc_backend_surface bsurface;
    struct wlc_context context;
@@ -55,6 +54,10 @@
    // Used to do visibility checks
    bool *blit;
 
+   // Scale of the output
+   // Affects virtual resolution by dividing with the scale
+   uint32_t scale;
+
    struct {
       struct wl_event_source *idle;
    } timer;
@@ -102,7 +105,7 @@
 
 void wlc_output_focus_ptr(struct wlc_output *output);
 void wlc_output_set_sleep_ptr(struct wlc_output *output, bool sleep);
-WLC_NONULLV(2) bool wlc_output_set_resolution_ptr(struct wlc_output *output, 
const struct wlc_size *resolution);
+WLC_NONULLV(2) bool wlc_output_set_resolution_ptr(struct wlc_output *output, 
const struct wlc_size *resolution, uint32_t scale);
 void wlc_output_set_mask_ptr(struct wlc_output *output, uint32_t mask);
 WLC_NONULLV(2) void wlc_output_get_pixels_ptr(struct wlc_output *output, bool 
(*pixels)(const struct wlc_size *size, uint8_t *rgba, void *arg), void *arg);
 bool wlc_output_set_views_ptr(struct wlc_output *output, const wlc_handle 
*views, size_t memb);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/compositor/seat/keyboard.c 
new/wlc-0.0.5/src/compositor/seat/keyboard.c
--- old/wlc-0.0.3/src/compositor/seat/keyboard.c        2016-05-22 
21:15:27.000000000 +0200
+++ new/wlc-0.0.5/src/compositor/seat/keyboard.c        2016-08-02 
19:57:11.000000000 +0200
@@ -142,7 +142,7 @@
    if (!(surface = wl_resource_from_wlc_resource(view->surface, "surface")))
       goto out;
 
-   if (is_x11_view(view))
+   if (is_x11_view(view) && (!new_focus || !is_x11_view(new_focus)))
       wlc_x11_window_set_active(&view->x11, false);
 
    wlc_resource *r;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/compositor/seat/pointer.c 
new/wlc-0.0.5/src/compositor/seat/pointer.c
--- old/wlc-0.0.3/src/compositor/seat/pointer.c 2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/compositor/seat/pointer.c 2016-08-02 19:57:11.000000000 
+0200
@@ -63,8 +63,27 @@
    return (view->mask & mask);
 }
 
+static bool
+is_inside_view_input_region(struct wlc_pointer *pointer, struct wlc_view *view)
+{
+   if (!view)
+      return false;
+
+   // FIXME: We should handle subsurfaces as well...
+
+   struct wlc_geometry b;
+   wlc_view_get_input(view, &b);
+
+   const struct wlc_geometry point = {
+      .origin = { .x = pointer->pos.x, .y = pointer->pos.y },
+      .size = { .w = 1, .h = 1 }
+   };
+
+   return wlc_geometry_contains(&b, &point);
+}
+
 static void
-find_surface_at_position_recursive(struct wlc_pointer *pointer, struct 
wlc_surface *parent, struct wlc_focused_surface *out)
+find_surface_at_position_recursive(const struct wlc_geometry *point, struct 
wlc_surface *parent, struct wlc_focused_surface *out)
 {
    wlc_resource *sub;
    chck_iter_pool_for_each(&parent->subsurface_list, sub) {
@@ -77,14 +96,17 @@
 
       out->offset.x += dx;
       out->offset.y += dy;
-      find_surface_at_position_recursive(pointer, subsurface, out);
+      find_surface_at_position_recursive(point, subsurface, out);
+
+      const struct wlc_geometry b = {
+         .origin = out->offset,
+         .size = subsurface->size
+      };
 
       if (out->id)
          return;
 
-      if (out->offset.x <= pointer->pos.x && out->offset.y <= pointer->pos.y &&
-            subsurface->size.w + out->offset.x >= pointer->pos.x &&
-            subsurface->size.h + out->offset.y >= pointer->pos.y) {
+      if (wlc_geometry_contains(&b, point)) {
          out->id = *sub;
          return;
       }
@@ -104,25 +126,28 @@
 
    out->id = 0;
 
+   const struct wlc_geometry point = {
+      .origin = { .x = pointer->pos.x, .y = pointer->pos.y },
+      .size = { .w = 1, .h = 1 }
+   };
+
    wlc_handle *h;
    chck_iter_pool_for_each_reverse(&output->views, h) {
       struct wlc_view *view;
       if (!(view = convert_from_wlc_handle(*h, "view")) || !view_visible(view, 
output->active.mask))
          continue;
 
-      struct wlc_geometry b;
-      wlc_view_get_bounds(view, &b, NULL);
+      struct wlc_geometry b, v;
+      wlc_view_get_bounds(view, &b, &v);
 
       struct wlc_surface *surface;
       if ((surface = convert_from_wlc_resource(view->surface, "surface"))) {
          out->offset = b.origin;
-         find_surface_at_position_recursive(pointer, surface, out);
+         find_surface_at_position_recursive(&point, surface, out);
 
          if (out->id) {
             return true;
-         } else if (b.origin.x <= pointer->pos.x && b.origin.y <= 
pointer->pos.y &&
-                    surface->size.w + b.origin.x >= pointer->pos.x &&
-                    surface->size.h + b.origin.y >= pointer->pos.y) {
+         } else if (wlc_geometry_contains(&v, &point)) {
             out->id = view->surface;
             return true;
          }
@@ -289,6 +314,9 @@
       }
    }
 
+   if (!is_inside_view_input_region(pointer, 
convert_from_wlc_handle(pointer->focused.view, "view")))
+      return;
+
    wlc_resource *r;
    chck_iter_pool_for_each(&pointer->focused.resources, r) {
       struct wl_resource *wr;
@@ -305,6 +333,9 @@
 {
    assert(pointer);
 
+   if (!is_inside_view_input_region(pointer, 
convert_from_wlc_handle(pointer->focused.view, "view")))
+      return;
+
    wlc_resource *r;
    chck_iter_pool_for_each(&pointer->focused.resources, r) {
       struct wl_resource *wr;
@@ -338,6 +369,9 @@
    if (!focused.id || !pass)
       return;
 
+   if (!is_inside_view_input_region(pointer, 
convert_from_wlc_handle(pointer->focused.view, "view")))
+      return;
+
    wlc_resource *r;
    chck_iter_pool_for_each(&pointer->focused.resources, r) {
       struct wl_resource *wr;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/compositor/seat/seat.c 
new/wlc-0.0.5/src/compositor/seat/seat.c
--- old/wlc-0.0.3/src/compositor/seat/seat.c    2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/compositor/seat/seat.c    2016-08-02 19:57:11.000000000 
+0200
@@ -145,11 +145,12 @@
 
    struct wlc_input_event *ev = data;
    struct wlc_output *output = 
convert_from_wlc_handle(compositor->active.output, "output");
+
+   const struct wlc_size resolution = (output ? output->virtual : 
wlc_size_zero);
+
    switch (ev->type) {
       case WLC_INPUT_EVENT_MOTION:
       {
-         const struct wlc_size resolution = (output ? output->resolution : 
wlc_size_zero);
-
          const struct wlc_pointer_origin pos = {
             chck_clamp(seat->pointer.pos.x + ev->motion.dx, 0, resolution.w),
             chck_clamp(seat->pointer.pos.y + ev->motion.dy, 0, resolution.h),
@@ -162,8 +163,6 @@
 
       case WLC_INPUT_EVENT_MOTION_ABSOLUTE:
       {
-         const struct wlc_size resolution = (output ? output->resolution : 
wlc_size_zero);
-
          const struct wlc_pointer_origin pos = {
             ev->motion_abs.x(ev->motion_abs.internal, resolution.w),
             ev->motion_abs.y(ev->motion_abs.internal, resolution.h)
@@ -183,8 +182,6 @@
 
       case WLC_INPUT_EVENT_BUTTON:
       {
-         const struct wlc_size resolution = (output ? output->resolution : 
wlc_size_zero);
-
          const struct wlc_pointer_origin pos = {
             chck_clamp(seat->pointer.pos.x, 0, resolution.w),
             chck_clamp(seat->pointer.pos.y, 0, resolution.h),
@@ -203,8 +200,6 @@
 
       case WLC_INPUT_EVENT_TOUCH:
       {
-         const struct wlc_size resolution = (output ? output->resolution : 
wlc_size_zero);
-
          struct wlc_point pos = {0, 0};
 
          if (ev->touch.x && ev->touch.y && ev->touch.internal) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/compositor/view.c 
new/wlc-0.0.5/src/compositor/view.c
--- old/wlc-0.0.3/src/compositor/view.c 2016-05-22 21:15:27.000000000 +0200
+++ new/wlc-0.0.5/src/compositor/view.c 2016-08-02 19:57:11.000000000 +0200
@@ -175,13 +175,6 @@
    }
 
    view->surface_commit = view->surface_pending;
-   wlc_dlog(WLC_DBG_COMMIT, "=> surface view %" PRIuWLC, 
convert_to_wlc_handle(view));
-}
-
-static bool
-should_be_transformed_by_parent(struct wlc_view *view)
-{
-   return !is_x11_view(view);
 }
 
 void
@@ -194,19 +187,21 @@
    if (!(surface = convert_from_wlc_resource(view->surface, "surface")))
       return;
 
-   if (should_be_transformed_by_parent(view)) {
-      for (struct wlc_view *parent = convert_from_wlc_handle(view->parent, 
"view"); parent; parent = convert_from_wlc_handle(parent->parent, "view")) {
-         out_bounds->origin.x += parent->commit.geometry.origin.x;
-         out_bounds->origin.y += parent->commit.geometry.origin.y;
-      }
-   }
-
-   if (view->xdg_surface && view->surface_commit.visible.size.w > 0 && 
view->surface_commit.visible.size.h > 0) {
+   if (view->xdg_surface && 
!wlc_size_equals(&view->surface_commit.visible.size, &wlc_size_zero)) {
       // xdg-surface client that draws drop shadows or other stuff.
-      out_bounds->origin.x -= view->surface_commit.visible.origin.x;
-      out_bounds->origin.y -= view->surface_commit.visible.origin.y;
-      out_bounds->size.w += surface->size.w - 
view->surface_commit.visible.size.w;
-      out_bounds->size.h += surface->size.h - 
view->surface_commit.visible.size.h;
+      struct wlc_geometry v = view->surface_commit.visible;
+      v.origin.x = chck_clamp32(v.origin.x, 0, surface->size.w);
+      v.origin.y = chck_clamp32(v.origin.y, 0, surface->size.h);
+      v.size.w = chck_clampu32(surface->size.w - v.size.w, 0, surface->size.w);
+      v.size.h = chck_clampu32(surface->size.h - v.size.h, 0, surface->size.h);
+
+      assert(surface->size.w > 0 && surface->size.h > 0);
+      const float wa = (float)out_bounds->size.w / surface->size.w, ha = 
(float)out_bounds->size.h / surface->size.h;
+
+      out_bounds->origin.x -= v.origin.x * wa;
+      out_bounds->origin.y -= v.origin.y * ha;
+      out_bounds->size.w += v.size.w * wa;
+      out_bounds->size.h += v.size.h * ha;
    }
 
    // Make sure bounds is never 0x0 w/h
@@ -221,16 +216,15 @@
       out_visible->size = surface->size;
 
       // Scale visible area retaining aspect
-      struct wlc_size ssize;
-      wlc_size_max(&surface->size, &(struct wlc_size){ 1, 1 }, &ssize);
+      assert(surface->size.w > 0 && surface->size.h > 0);
       const float ba = (float)out_bounds->size.w / (float)out_bounds->size.h;
-      const float sa = (float)ssize.w / (float)ssize.h;
+      const float sa = (float)surface->size.w / (float)surface->size.h;
       if (ba < sa) {
-         out_visible->size.w *= (float)out_bounds->size.w / ssize.w;
-         out_visible->size.h *= (float)out_bounds->size.w / ssize.w;
+         out_visible->size.w *= (float)out_bounds->size.w / surface->size.w;
+         out_visible->size.h *= (float)out_bounds->size.w / surface->size.w;
       } else {
-         out_visible->size.w *= (float)out_bounds->size.h / ssize.h;
-         out_visible->size.h *= (float)out_bounds->size.h / ssize.h;
+         out_visible->size.w *= (float)out_bounds->size.h / surface->size.h;
+         out_visible->size.h *= (float)out_bounds->size.h / surface->size.h;
       }
 
       // Center visible area
@@ -250,32 +244,25 @@
 wlc_view_get_opaque(struct wlc_view *view, struct wlc_geometry *out_opaque)
 {
    assert(view && out_opaque);
-   memcpy(out_opaque, &wlc_geometry_zero, sizeof(struct wlc_geometry));
-
-   struct wlc_surface *surface;
-   if (!(surface = convert_from_wlc_resource(view->surface, "surface")))
-      return true;
 
    struct wlc_geometry b, v;
    wlc_view_get_bounds(view, &b, &v);
+   return wlc_surface_get_opaque(convert_from_wlc_resource(view->surface, 
"surface"), &v.origin, out_opaque);
+}
 
-   const bool opaque = ((surface->pending.opaque.extents.x1 + 
surface->pending.opaque.extents.y1 + surface->pending.opaque.extents.x2 + 
surface->pending.opaque.extents.y2) > 0);
+void
+wlc_view_get_input(struct wlc_view *view, struct wlc_geometry *out_input)
+{
+   assert(view && out_input);
+   struct wlc_geometry b, v;
+   wlc_view_get_bounds(view, &b, &v);
 
-   if (opaque && (wlc_size_equals(&surface->size, &b.size) || 
wlc_geometry_equals(&v, &b))) {
-      // Only ran when we don't draw black borders behind the view
-      const float miw = chck_minf(surface->size.w, b.size.w), maw = 
chck_maxf(surface->size.w, b.size.w);
-      const float mih = chck_minf(surface->size.h, b.size.h), mah = 
chck_maxf(surface->size.h, b.size.h);
-      const int32_t dw = surface->size.w - (surface->pending.opaque.extents.x2 
- surface->pending.opaque.extents.x1);
-      const int32_t dh = surface->size.h - (surface->pending.opaque.extents.y2 
- surface->pending.opaque.extents.y1);
-      b.origin.x += surface->pending.opaque.extents.x1 * miw / maw;
-      b.origin.y += surface->pending.opaque.extents.y1 * mih / mah;
-      b.size.w -= dw * miw / maw;
-      b.size.h -= dh * mih / mah;
-      // printf("O: %ux%u+%d,%d\n", b.size.w, b.size.h, b.origin.x, 
b.origin.y);
+   if (is_x11_view(view)) {
+      *out_input = v;
+      return;
    }
 
-   memcpy(out_opaque, &b, sizeof(b));
-   return opaque;
+   wlc_surface_get_input(convert_from_wlc_resource(view->surface, "surface"), 
&v.origin, out_input);
 }
 
 bool
@@ -459,6 +446,16 @@
 }
 
 void
+wlc_view_set_pid_ptr(struct wlc_view *view, pid_t pid)
+{
+   if (!view || view->data.pid == pid)
+      return;
+
+   view->data.pid = pid;
+   WLC_INTERFACE_EMIT(view.properties_updated, convert_to_wlc_handle(view), 
WLC_BIT_PROPERTY_PID);
+}
+
+void
 wlc_view_close_ptr(struct wlc_view *view)
 {
    if (!view)
@@ -668,6 +665,22 @@
    return get_cstr(convert_from_wlc_handle(view, "view"), offsetof(struct 
wlc_view, data.app_id));
 }
 
+WLC_API pid_t
+wlc_view_get_pid(wlc_handle handle)
+{
+   struct wlc_view *view;
+   if(!(view = convert_from_wlc_handle(handle, "view")))
+      return 0;
+
+   if (is_x11_view(view)) {
+      return view->data.pid;
+   } else {
+      pid_t pid;
+      wl_client_get_credentials(wlc_view_get_client_ptr(view), &pid, NULL, 
NULL);
+      return pid;
+   }
+}
+
 void
 wlc_view_release(struct wlc_view *view)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/compositor/view.h 
new/wlc-0.0.5/src/compositor/view.h
--- old/wlc-0.0.3/src/compositor/view.h 2016-05-22 21:15:27.000000000 +0200
+++ new/wlc-0.0.5/src/compositor/view.h 2016-08-02 19:57:11.000000000 +0200
@@ -2,6 +2,7 @@
 #define _WLC_VIEW_H_
 
 #include <stdbool.h>
+#include <sys/types.h>
 #include <wlc/geometry.h>
 #include <wayland-util.h>
 #include <chck/pool/pool.h>
@@ -47,6 +48,7 @@
       struct chck_string app_id;
       struct chck_string title;
       struct chck_string _class;
+      pid_t pid;
       enum wl_shell_surface_fullscreen_method fullscreen_mode;
       bool minimized;
    } data;
@@ -72,6 +74,7 @@
 WLC_NONULL void wlc_view_ack_surface_attach(struct wlc_view *view, struct 
wlc_surface *surface);
 WLC_NONULLV(1,2) void wlc_view_get_bounds(struct wlc_view *view, struct 
wlc_geometry *out_bounds, struct wlc_geometry *out_visible);
 WLC_NONULL bool wlc_view_get_opaque(struct wlc_view *view, struct wlc_geometry 
*out_opaque);
+WLC_NONULL void wlc_view_get_input(struct wlc_view *view, struct wlc_geometry 
*out_input);
 WLC_NONULL bool wlc_view_request_geometry(struct wlc_view *view, const struct 
wlc_geometry *r);
 bool wlc_view_request_state(struct wlc_view *view, enum wlc_view_state_bit 
state, bool toggle);
 void wlc_view_set_surface(struct wlc_view *view, struct wlc_surface *surface);
@@ -98,5 +101,6 @@
 void wlc_view_set_title_ptr(struct wlc_view *view, const char *title, size_t 
length);
 void wlc_view_set_class_ptr(struct wlc_view *view, const char *class_, size_t 
length);
 void wlc_view_set_app_id_ptr(struct wlc_view *view, const char *app_id);
+void wlc_view_set_pid_ptr(struct wlc_view *view, pid_t pid);
 
 #endif /* _WLC_VIEW_H_ */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/platform/backend/backend.c 
new/wlc-0.0.5/src/platform/backend/backend.c
--- old/wlc-0.0.3/src/platform/backend/backend.c        2016-05-22 
21:15:27.000000000 +0200
+++ new/wlc-0.0.5/src/platform/backend/backend.c        2016-08-02 
19:57:11.000000000 +0200
@@ -3,10 +3,11 @@
 #include <assert.h>
 #include "internal.h"
 #include "backend.h"
+#include "drm.h"
+
 #ifdef ENABLE_X11_BACKEND
-#include "x11.h"
+#  include "x11.h"
 #endif
-#include "drm.h"
 
 bool
 wlc_backend_surface(struct wlc_backend_surface *surface, void 
(*destructor)(struct wlc_backend_surface*), size_t internal_size)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/platform/backend/backend.h 
new/wlc-0.0.5/src/platform/backend/backend.h
--- old/wlc-0.0.3/src/platform/backend/backend.h        2016-05-22 
21:15:27.000000000 +0200
+++ new/wlc-0.0.5/src/platform/backend/backend.h        2016-08-02 
19:57:11.000000000 +0200
@@ -5,7 +5,6 @@
 #include <stdbool.h>
 #include "EGL/egl.h"
 
-struct wlc_output;
 struct chck_pool;
 
 struct wlc_backend_surface {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/platform/backend/drm.c 
new/wlc-0.0.5/src/platform/backend/drm.c
--- old/wlc-0.0.3/src/platform/backend/drm.c    2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/platform/backend/drm.c    2016-08-02 19:57:11.000000000 
+0200
@@ -349,7 +349,6 @@
       info->info.physical_width = connector->mmWidth;
       info->info.physical_height = connector->mmHeight;
       info->info.subpixel = connector->subpixel;
-      info->info.scale = 1; // weston gets this from config?
       info->info.connector_id = connector->connector_type_id;
       info->info.connector = 
wlc_connector_for_drm_connector(connector->connector_type);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/platform/backend/x11.c 
new/wlc-0.0.5/src/platform/backend/x11.c
--- old/wlc-0.0.3/src/platform/backend/x11.c    2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/platform/backend/x11.c    2016-08-02 19:57:11.000000000 
+0200
@@ -183,7 +183,7 @@
             struct wlc_output *output;
             if ((output = output_for_window(&compositor->outputs.pool, 
ev->window))) {
                output->mode = (struct wlc_size){ ev->width, ev->height };
-               wlc_output_set_resolution_ptr(output, &output->mode); // XXX: 
make a request?
+               wlc_output_set_resolution_ptr(output, &output->mode, 
output->scale); // XXX: make a request?
             }
          }
          break;
@@ -226,6 +226,11 @@
             case XCB_BUTTON_PRESS:
             {
                xcb_button_press_event_t *xev = 
(xcb_button_press_event_t*)event;
+
+               // do not send scroll up / down events
+               if (xev->detail >= 4 && xev->detail <= 7)
+                  break;
+
                struct wlc_input_event ev = {0};
                ev.type = WLC_INPUT_EVENT_BUTTON;
                ev.time = xev->time;
@@ -307,7 +312,6 @@
    wlc_output_information(info);
    chck_string_set_cstr(&info->make, "Xorg", false);
    chck_string_set_cstr(&info->model, "X11 Window", false);
-   info->scale = 1;
    info->connector = WLC_CONNECTOR_WLC;
    info->connector_id = id;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/platform/render/gles2.c 
new/wlc-0.0.5/src/platform/render/gles2.c
--- old/wlc-0.0.3/src/platform/render/gles2.c   2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/platform/render/gles2.c   2016-08-02 19:57:11.000000000 
+0200
@@ -18,6 +18,7 @@
 #include "resources/types/buffer.h"
 
 static bool DRAW_OPAQUE = false;
+static bool DRAW_INPUT = false;
 
 static const GLubyte cursor_palette[];
 
@@ -42,6 +43,8 @@
 
 enum {
    TEXTURE_BLACK,
+   TEXTURE_RED,
+   TEXTURE_BLUE,
    TEXTURE_CURSOR,
    TEXTURE_FAKEFB,
    TEXTURE_LAST
@@ -72,10 +75,13 @@
    } programs[PROGRAM_LAST];
 
    struct wlc_size resolution, mode;
+   uint32_t scale;
+
    GLuint textures[TEXTURE_LAST];
    GLuint clear_fbo;
    GLenum internal_format;
    GLenum preferred_type;
+   bool native_resolution;
    bool fakefb_dirty;
 
    struct {
@@ -379,6 +385,8 @@
       const void *data;
    } images[TEXTURE_LAST] = {
       { GL_LUMINANCE, 1, 1, GL_UNSIGNED_BYTE, NULL }, // TEXTURE_BLACK
+      { GL_RGB, 1, 1, GL_UNSIGNED_BYTE, (GLubyte[]){255, 0, 0} }, // 
TEXTURE_RED
+      { GL_RGB, 1, 1, GL_UNSIGNED_BYTE, (GLubyte[]){0, 0, 255} }, // 
TEXTURE_BLUE
       { GL_LUMINANCE, 14, 14, GL_UNSIGNED_BYTE, cursor_palette }, // 
TEXTURE_CURSOR
       { GL_RGBA, 0, 0, GL_UNSIGNED_BYTE, NULL }, // TEXTURE_FAKEFB
    };
@@ -417,9 +425,9 @@
 }
 
 static void
-resolution(struct ctx *context, const struct wlc_size *mode, const struct 
wlc_size *resolution)
+resolution(struct ctx *context, const struct wlc_size *mode, const struct 
wlc_size *resolution, uint32_t scale)
 {
-   assert(context && resolution);
+   assert(context && resolution && scale > 0);
 
    if (!wlc_size_equals(&context->resolution, resolution)) {
       for (GLuint i = 0; i < PROGRAM_LAST; ++i) {
@@ -437,6 +445,10 @@
       GL_CALL(glViewport(0, 0, mode->w, mode->h));
       context->mode = *mode;
    }
+
+   struct wlc_size virtual = { .w = mode->w / (float)scale, .h = mode->h / 
(float)scale };
+   context->native_resolution = wlc_size_equals(resolution, &virtual);
+   context->scale = scale;
 }
 
 static void
@@ -673,7 +685,7 @@
       GL_CALL(glActiveTexture(GL_TEXTURE0 + i));
       GL_CALL(glBindTexture(GL_TEXTURE_2D, textures[i]));
 
-      if (settings->filter || !wlc_size_equals(&context->resolution, 
&context->mode)) {
+      if (settings->filter || !context->native_resolution) {
          GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
GL_LINEAR));
          GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
GL_LINEAR));
       } else {
@@ -694,6 +706,9 @@
 
    const struct wlc_geometry *g = geometry;
 
+   assert(surface->commit.scale >= 1);
+   settings->filter = ((uint32_t)surface->commit.scale != context->scale);
+
    if (!wlc_size_equals(&surface->size, &geometry->size)) {
       if (wlc_geometry_equals(&settings->visible, geometry)) {
          settings->filter = true;
@@ -717,6 +732,22 @@
    settings.program = (enum program_type)surface->format;
    settings.visible = *geometry;
    surface_paint_internal(context, surface, geometry, &settings);
+
+   if (DRAW_OPAQUE) {
+      wlc_surface_get_opaque(surface, &geometry->origin, &settings.visible);
+      settings.program = PROGRAM_RGB;
+      GL_CALL(glBlendFunc(GL_ONE, GL_DST_COLOR));
+      texture_paint(context, &context->textures[TEXTURE_RED], 1, 
&settings.visible, &settings);
+      GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
+   }
+
+   if (DRAW_INPUT) {
+      wlc_surface_get_input(surface, &geometry->origin, &settings.visible);
+      settings.program = PROGRAM_RGB;
+      GL_CALL(glBlendFunc(GL_ONE, GL_DST_COLOR));
+      texture_paint(context, &context->textures[TEXTURE_BLUE], 1, 
&settings.visible, &settings);
+      GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
+   }
 }
 
 static void
@@ -737,11 +768,18 @@
    surface_paint_internal(context, surface, &geometry, &settings);
 
    if (DRAW_OPAQUE) {
-      wlc_view_get_opaque(view, &geometry);
-      settings.visible = geometry;
-      settings.program = PROGRAM_CURSOR;
+      wlc_view_get_opaque(view, &settings.visible);
+      settings.program = PROGRAM_RGB;
+      GL_CALL(glBlendFunc(GL_ONE, GL_DST_COLOR));
+      texture_paint(context, &context->textures[TEXTURE_RED], 1, 
&settings.visible, &settings);
+      GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
+   }
+
+   if (DRAW_INPUT) {
+      wlc_view_get_input(view, &settings.visible);
+      settings.program = PROGRAM_RGB;
       GL_CALL(glBlendFunc(GL_ONE, GL_DST_COLOR));
-      texture_paint(context, &context->textures[TEXTURE_BLACK], 1, &geometry, 
&settings);
+      texture_paint(context, &context->textures[TEXTURE_BLUE], 1, 
&settings.visible, &settings);
       GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
    }
 }
@@ -791,7 +829,7 @@
    (void)context;
    assert(context && geometry && out_geometry && out_data);
    struct wlc_geometry g = *geometry;
-   clamp_to_bounds(&g, &context->resolution);
+   clamp_to_bounds(&g, &context->mode);
    GL_CALL(glReadPixels(g.origin.x, g.origin.y, g.size.w, g.size.h, 
format_map[format].format, format_map[format].type, out_data));
    *out_geometry = g;
 }
@@ -802,7 +840,7 @@
    (void)context;
    assert(context && geometry && data);
    struct wlc_geometry g = *geometry;
-   clamp_to_bounds(&g, &context->resolution);
+   clamp_to_bounds(&g, &context->mode);
    GL_CALL(glBindTexture(GL_TEXTURE_2D, context->textures[TEXTURE_FAKEFB]));
    GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, g.origin.x, g.origin.y, g.size.w, 
g.size.h, format_map[format].format, format_map[format].type, data));
    context->fakefb_dirty = true;
@@ -868,6 +906,7 @@
    api->clear = clear;
 
    chck_cstr_to_bool(getenv("WLC_DRAW_OPAQUE"), &DRAW_OPAQUE);
+   chck_cstr_to_bool(getenv("WLC_DRAW_INPUT"), &DRAW_INPUT);
 
    wlc_log(WLC_LOG_INFO, "GLES2 renderer initialized");
    return ctx;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/platform/render/render.c 
new/wlc-0.0.5/src/platform/render/render.c
--- old/wlc-0.0.3/src/platform/render/render.c  2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/platform/render/render.c  2016-08-02 19:57:11.000000000 
+0200
@@ -6,14 +6,14 @@
 #include "gles2.h"
 
 void
-wlc_render_resolution(struct wlc_render *render, struct wlc_context *bound, 
const struct wlc_size *mode, const struct wlc_size *resolution)
+wlc_render_resolution(struct wlc_render *render, struct wlc_context *bound, 
const struct wlc_size *mode, const struct wlc_size *resolution, uint32_t scale)
 {
    assert(render && bound && mode && resolution);
 
    if (!render->api.resolution || !wlc_context_bind(bound))
       return;
 
-   render->api.resolution(render->render, mode, resolution);
+   render->api.resolution(render->render, mode, resolution, scale);
 }
 
 void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/platform/render/render.h 
new/wlc-0.0.5/src/platform/render/render.h
--- old/wlc-0.0.3/src/platform/render/render.h  2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/platform/render/render.h  2016-08-02 19:57:11.000000000 
+0200
@@ -19,7 +19,7 @@
 struct wlc_render_api {
    enum wlc_renderer renderer_type;
    WLC_NONULL void (*terminate)(struct ctx *render);
-   WLC_NONULL void (*resolution)(struct ctx *render, const struct wlc_size 
*mode, const struct wlc_size *resolution);
+   WLC_NONULL void (*resolution)(struct ctx *render, const struct wlc_size 
*mode, const struct wlc_size *resolution, uint32_t scale);
    WLC_NONULL void (*surface_destroy)(struct ctx *render, struct wlc_context 
*bound, struct wlc_surface *surface);
    WLC_NONULLV(1,2,3) bool (*surface_attach)(struct ctx *render, struct 
wlc_context *bound, struct wlc_surface *surface, struct wlc_buffer *buffer);
    WLC_NONULL void (*view_paint)(struct ctx *render, struct wlc_view *view);
@@ -36,7 +36,7 @@
    struct wlc_render_api api;
 };
 
-WLC_NONULL void wlc_render_resolution(struct wlc_render *render, struct 
wlc_context *bound, const struct wlc_size *mode, const struct wlc_size 
*resolution);
+WLC_NONULL void wlc_render_resolution(struct wlc_render *render, struct 
wlc_context *bound, const struct wlc_size *mode, const struct wlc_size 
*resolution, uint32_t scale);
 WLC_NONULL void wlc_render_surface_destroy(struct wlc_render *render, struct 
wlc_context *bound, struct wlc_surface *surface);
 WLC_NONULLV(1,2,3) bool wlc_render_surface_attach(struct wlc_render *render, 
struct wlc_context *bound, struct wlc_surface *surface, struct wlc_buffer 
*buffer);
 WLC_NONULL void wlc_render_view_paint(struct wlc_render *render, struct 
wlc_context *bound, struct wlc_view *view);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/resources/types/surface.c 
new/wlc-0.0.5/src/resources/types/surface.c
--- old/wlc-0.0.3/src/resources/types/surface.c 2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/resources/types/surface.c 2016-08-02 19:57:11.000000000 
+0200
@@ -10,6 +10,7 @@
 #include "macros.h"
 #include "compositor/output.h"
 #include "compositor/view.h"
+#include <chck/math/math.h>
 
 static void
 surface_attach(struct wlc_surface *surface, struct wlc_buffer *buffer)
@@ -46,14 +47,7 @@
 static void
 commit_state(struct wlc_surface *surface, struct wlc_surface_state *pending, 
struct wlc_surface_state *out)
 {
-   if (pending->attached) {
-      surface_attach(surface, convert_from_wlc_resource(pending->buffer, 
"buffer"));
-      pending->attached = false;
-   }
-
-   state_set_buffer(out, convert_from_wlc_resource(pending->buffer, "buffer"));
-   state_set_buffer(pending, NULL);
-
+   out->scale = chck_max32(pending->scale, 1);
    pending->offset = wlc_point_zero;
 
    wlc_resource *r;
@@ -75,6 +69,25 @@
    pixman_region32_fini(&opaque);
 
    pixman_region32_intersect_rect(&out->input, &pending->input, 0, 0, 
surface->size.w, surface->size.h);
+
+   if (pending->attached) {
+      surface_attach(surface, convert_from_wlc_resource(pending->buffer, 
"buffer"));
+      pending->attached = false;
+   }
+
+   state_set_buffer(out, convert_from_wlc_resource(pending->buffer, "buffer"));
+   state_set_buffer(pending, NULL);
+}
+
+static void
+init_state(struct wlc_surface_state *state)
+{
+   assert(state);
+   pixman_region32_init_rect(&state->opaque, 0, 0, 0, 0);
+   pixman_region32_init_rect(&state->damage, 0, 0, 0, 0);
+   pixman_region32_init_rect(&state->input, INT32_MIN, INT32_MIN, UINT32_MAX, 
UINT32_MAX);
+   state->scale = 1;
+   state->subsurface_position = (struct wlc_point){0, 0};
 }
 
 static void
@@ -252,7 +265,70 @@
       return;
    }
 
-   surface->pending.scale = 1;
+   surface->pending.scale = scale;
+}
+
+bool
+wlc_surface_get_opaque(struct wlc_surface *surface, const struct wlc_point 
*offset, struct wlc_geometry *out_opaque)
+{
+   *out_opaque = wlc_geometry_zero;
+
+   if (!surface)
+      return false;
+
+   assert(offset && out_opaque);
+   const bool opaque = ((surface->commit.opaque.extents.x1 + 
surface->commit.opaque.extents.y1 + surface->commit.opaque.extents.x2 + 
surface->commit.opaque.extents.y2) > 0);
+
+   if (opaque) {
+      struct wlc_geometry o = {
+         .origin = {
+            chck_min32(surface->commit.opaque.extents.x1, surface->size.w),
+            chck_min32(surface->commit.opaque.extents.y1, surface->size.h),
+         },
+      };
+
+      o.size.w = chck_clamp32(surface->commit.opaque.extents.x2, o.origin.x, 
surface->size.w),
+      o.size.h = chck_clamp32(surface->commit.opaque.extents.y2, o.origin.y, 
surface->size.h),
+      assert((int32_t)o.size.w >= o.origin.x && (int32_t)o.size.h >= 
o.origin.y);
+
+      struct wlc_geometry v;
+      v.origin.x = offset->x + o.origin.x * surface->coordinate_transform.w;
+      v.origin.y = offset->y + o.origin.y * surface->coordinate_transform.h;
+      v.size.w = (o.size.w - o.origin.x) * surface->coordinate_transform.w;
+      v.size.h = (o.size.h - o.origin.y) * surface->coordinate_transform.h;
+      *out_opaque = v;
+   } else {
+      struct wlc_geometry v = {
+         .origin = *offset,
+         .size = {
+            .w = surface->size.w * surface->coordinate_transform.w,
+            .h = surface->size.h * surface->coordinate_transform.h,
+         }
+      };
+      *out_opaque = v;
+   }
+
+   return opaque;
+}
+
+void
+wlc_surface_get_input(struct wlc_surface *surface, const struct wlc_point 
*offset, struct wlc_geometry *out_input)
+{
+   *out_input = wlc_geometry_zero;
+
+   if (!surface)
+      return;
+
+   assert(offset && out_input);
+   assert(surface->commit.input.extents.x2 >= 
surface->commit.input.extents.x1);
+   assert(surface->commit.input.extents.y2 >= 
surface->commit.input.extents.y1);
+
+   struct wlc_geometry v;
+   v.origin.x = offset->x + surface->commit.input.extents.x1 * 
surface->coordinate_transform.w;
+   v.origin.y = offset->y + surface->commit.input.extents.y1 * 
surface->coordinate_transform.h;
+   v.size.w = (surface->commit.input.extents.x2 - 
surface->commit.input.extents.x1) * surface->coordinate_transform.w;
+   v.size.h = (surface->commit.input.extents.y2 - 
surface->commit.input.extents.y1) * surface->coordinate_transform.h;
+   *out_input = v;
 }
 
 struct wlc_buffer*
@@ -287,17 +363,25 @@
    if (buffer)
       size = buffer->size;
 
+   wlc_size_max(&size, &size, &(struct wlc_size){1, 1});
+   size.w /= surface->commit.scale;
+   size.h /= surface->commit.scale;
    surface->size = size;
 
-   if (surface->view) {
-      struct wlc_view *view = convert_from_wlc_handle(surface->view, "view");
+   struct wlc_view *view;
+   if (surface->view && (view = convert_from_wlc_handle(surface->view, 
"view"))) {
       struct wlc_geometry g, area;
-
-      struct wlc_size ssize = { 1, 1 };
-      wlc_size_max(&ssize, &surface->size, &ssize);
       wlc_view_get_bounds(view, &g, &area);
-      surface->coordinate_transform.w = (float)(area.size.w) / ssize.w;
-      surface->coordinate_transform.h = (float)(area.size.h) / ssize.h;
+      surface->coordinate_transform.w = (float)(area.size.w) / size.w;
+      surface->coordinate_transform.h = (float)(area.size.h) / size.h;
+   } else {
+      surface->coordinate_transform = (struct wlc_coordinate_scale) {1, 1};
+   }
+
+   struct wlc_surface *p;
+   if ((p = convert_from_wlc_resource(surface->parent, "surface"))) {
+      surface->coordinate_transform.w *= p->coordinate_transform.w;
+      surface->coordinate_transform.h *= p->coordinate_transform.h;
    }
 
    surface->commit.attached = (buffer ? true : false);
@@ -391,10 +475,10 @@
        !chck_iter_pool(&surface->subsurface_list, 4, 0, sizeof(wlc_resource)))
       goto fail;
 
-   surface->pending.subsurface_position = (struct wlc_point){0, 0};
-   surface->coordinate_transform = (struct wlc_coordinate_scale) {1, 1};
+   init_state(&surface->pending);
+   init_state(&surface->commit);
+   surface->coordinate_transform = (struct wlc_coordinate_scale){1, 1};
    surface->parent_synchronized = false;
-
    return true;
 
 fail:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/resources/types/surface.h 
new/wlc-0.0.5/src/resources/types/surface.h
--- old/wlc-0.0.3/src/resources/types/surface.h 2016-05-22 21:15:27.000000000 
+0200
+++ new/wlc-0.0.5/src/resources/types/surface.h 2016-08-02 19:57:11.000000000 
+0200
@@ -50,7 +50,7 @@
    wlc_handle parent_view;
 
    /* Current output the surface is attached to */
-   wlc_resource output;
+   wlc_handle output;
 
    /**
     * "Texture" as we use OpenGL terminology, but can be id to anything.
@@ -69,6 +69,8 @@
    bool synchronized, parent_synchronized;
 };
 
+WLC_NONULLV(2,3) bool wlc_surface_get_opaque(struct wlc_surface *surface, 
const struct wlc_point *offset, struct wlc_geometry *out_opaque);
+WLC_NONULLV(2,3) void wlc_surface_get_input(struct wlc_surface *surface, const 
struct wlc_point *offset, struct wlc_geometry *out_input);
 struct wlc_buffer* wlc_surface_get_buffer(struct wlc_surface *surface);
 void wlc_surface_attach_to_view(struct wlc_surface *surface, struct wlc_view 
*view);
 bool wlc_surface_attach_to_output(struct wlc_surface *surface, struct 
wlc_output *output, struct wlc_buffer *buffer);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/xwayland/xwm.c 
new/wlc-0.0.5/src/xwayland/xwm.c
--- old/wlc-0.0.3/src/xwayland/xwm.c    2016-05-22 21:15:27.000000000 +0200
+++ new/wlc-0.0.5/src/xwayland/xwm.c    2016-08-02 19:57:11.000000000 +0200
@@ -181,7 +181,7 @@
 }
 
 static void
-read_properties(struct wlc_xwm *xwm, struct wlc_x11_window *win)
+read_properties(struct wlc_xwm *xwm, struct wlc_x11_window *win, const 
xcb_atom_t *props, size_t nmemb)
 {
    assert(win);
 
@@ -189,112 +189,99 @@
    if (!(view = view_for_window(win)))
       return;
 
-#define TYPE_WM_PROTOCOLS    XCB_ATOM_CUT_BUFFER0
-#define TYPE_MOTIF_WM_HINTS  XCB_ATOM_CUT_BUFFER1
-#define TYPE_NET_WM_STATE    XCB_ATOM_CUT_BUFFER2
-#define TYPE_WM_NORMAL_HINTS XCB_ATOM_CUT_BUFFER3
-
-   const struct {
-      xcb_atom_t atom;
-      xcb_atom_t type;
-   } props[] = {
-      { XCB_ATOM_WM_CLASS, XCB_ATOM_STRING },
-      { XCB_ATOM_WM_NAME, XCB_ATOM_STRING },
-      { XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW },
-      { x11.atoms[WM_PROTOCOLS], TYPE_WM_PROTOCOLS },
-      { x11.atoms[WM_NORMAL_HINTS], TYPE_WM_NORMAL_HINTS },
-      { x11.atoms[NET_WM_STATE], TYPE_NET_WM_STATE },
-      { x11.atoms[NET_WM_WINDOW_TYPE], XCB_ATOM_ATOM },
-      { x11.atoms[NET_WM_NAME], XCB_ATOM_STRING },
-      { x11.atoms[NET_WM_PID], XCB_ATOM_CARDINAL },
-      { x11.atoms[MOTIF_WM_HINTS], TYPE_MOTIF_WM_HINTS },
-   };
-
    xcb_get_property_cookie_t *cookies;
-   if (!(cookies = chck_calloc_of(LENGTH(props), 
sizeof(xcb_get_property_cookie_t))))
+   if (!(cookies = chck_calloc_of(nmemb, sizeof(xcb_get_property_cookie_t))))
       return;
 
-   for (uint32_t i = 0; i < LENGTH(props); ++i)
-      cookies[i] = xcb_get_property(x11.connection, 0, win->id, props[i].atom, 
XCB_ATOM_ANY, 0, 2048);
+   for (uint32_t i = 0; i < nmemb; ++i)
+      cookies[i] = xcb_get_property(x11.connection, 0, win->id, props[i], 
XCB_ATOM_ANY, 0, 2048);
 
-   for (uint32_t i = 0; i < LENGTH(props); ++i) {
+   for (uint32_t i = 0; i < nmemb; ++i) {
       xcb_get_property_reply_t *reply;
       if (!(reply = xcb_get_property_reply(x11.connection, cookies[i], NULL)))
          continue;
 
-      if (reply->type == XCB_ATOM_NONE) {
-         free(reply);
-         continue;
-      }
-
-      switch (props[i].type) {
-         case XCB_ATOM_STRING:
-            // Class && Name
-            if (props[i].atom == XCB_ATOM_WM_CLASS) {
-               wlc_view_set_class_ptr(view, xcb_get_property_value(reply), 
xcb_get_property_value_length(reply));
-            } else if (props[i].atom == XCB_ATOM_WM_NAME) {
+      if (reply->type == XCB_ATOM_STRING || reply->type == 
x11.atoms[UTF8_STRING]) {
+         // Class && Name
+         // STRING == latin1, but we naively just read it as is. For full 
support we should convert to utf8.
+         if (props[i] == XCB_ATOM_WM_CLASS) {
+            wlc_view_set_class_ptr(view, xcb_get_property_value(reply), 
xcb_get_property_value_length(reply));
+            wlc_dlog(WLC_DBG_XWM, "WM_CLASS: %s", view->data._class.data);
+         } else if (props[i] == XCB_ATOM_WM_NAME || props[i] == 
x11.atoms[NET_WM_NAME]) {
+            if (reply->type != XCB_ATOM_STRING  || !win->has_utf8_title) {
                wlc_view_set_title_ptr(view, xcb_get_property_value(reply), 
xcb_get_property_value_length(reply));
+               win->has_utf8_title = true;
             }
-            break;
-         case XCB_ATOM_WINDOW:
-         {
-            // Transient
-            xcb_window_t *xid = xcb_get_property_value(reply);
-            set_parent(xwm, win, *xid);
+            wlc_dlog(WLC_DBG_XWM, "(%d) %s %s %s", win->has_utf8_title, 
(reply->type == XCB_ATOM_STRING ? "STRING" : "UTF8_STRING"), (props[i] == 
XCB_ATOM_WM_NAME ? "WM_NAME" : "NET_WM_NAME"), view->data.title.data);
          }
-         break;
-         case XCB_ATOM_CARDINAL:
-            // PID
-            break;
-         case XCB_ATOM_ATOM:
-         {
-            // Window type
-            view->type &= ~WLC_BIT_UNMANAGED | ~WLC_BIT_SPLASH | 
~WLC_BIT_MODAL;
-            xcb_atom_t *atoms = xcb_get_property_value(reply);
-            for (uint32_t i = 0; i < reply->value_len; ++i) {
-               if (atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_TOOLTIP] ||
-                   atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_UTILITY] ||
-                   atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_DND] ||
-                   atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_DROPDOWN_MENU] ||
-                   atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_POPUP_MENU] ||
-                   atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_COMBO]) {
-                  wlc_view_set_type_ptr(view, WLC_BIT_UNMANAGED, true);
-               }
-               if (atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_DIALOG])
-                  wlc_view_set_type_ptr(view, WLC_BIT_MODAL, true);
-               if (atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_SPLASH])
-                  wlc_view_set_type_ptr(view, WLC_BIT_SPLASH, true);
+      } else if (props[i] == XCB_ATOM_WM_TRANSIENT_FOR && reply->type == 
XCB_ATOM_WINDOW) {
+         // Transient
+         xcb_window_t *xid = xcb_get_property_value(reply);
+         set_parent(xwm, win, *xid);
+         wlc_dlog(WLC_DBG_XWM, "WM_TRANSIENT_FOR: %u", *xid);
+      } else if (props[i] == x11.atoms[NET_WM_PID] && reply->type == 
XCB_ATOM_CARDINAL) {
+         // PID
+         wlc_view_set_pid_ptr(view, *(pid_t *)xcb_get_property_value(reply));
+         wlc_dlog(WLC_DBG_XWM, "NET_WM_PID");
+      } else if (props[i] == x11.atoms[NET_WM_WINDOW_TYPE] && reply->type == 
XCB_ATOM_ATOM) {
+         // Window type
+         view->type &= ~WLC_BIT_UNMANAGED | ~WLC_BIT_SPLASH | ~WLC_BIT_MODAL;
+         xcb_atom_t *atoms = xcb_get_property_value(reply);
+         for (uint32_t i = 0; i < reply->value_len; ++i) {
+            if (atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_TOOLTIP] ||
+                  atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_UTILITY] ||
+                  atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_DND] ||
+                  atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_DROPDOWN_MENU] ||
+                  atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_POPUP_MENU] ||
+                  atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_COMBO]) {
+               wlc_view_set_type_ptr(view, WLC_BIT_UNMANAGED, true);
             }
+            if (atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_DIALOG])
+               wlc_view_set_type_ptr(view, WLC_BIT_MODAL, true);
+            if (atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_SPLASH])
+               wlc_view_set_type_ptr(view, WLC_BIT_SPLASH, true);
          }
-         break;
-         case TYPE_WM_PROTOCOLS:
-         {
-            xcb_atom_t *atoms = xcb_get_property_value(reply);
-            for (uint32_t i = 0; i < reply->value_len; ++i) {
-               if (atoms[i] == x11.atoms[WM_DELETE_WINDOW])
-                  win->has_delete_window = true;
-            }
+         wlc_dlog(WLC_DBG_XWM, "NET_WM_WINDOW_TYPE: %u", view->type);
+      } else if (props[i] == x11.atoms[WM_PROTOCOLS]) {
+         xcb_atom_t *atoms = xcb_get_property_value(reply);
+         for (uint32_t i = 0; i < reply->value_len; ++i) {
+            if (atoms[i] == x11.atoms[WM_DELETE_WINDOW])
+               win->has_delete_window = true;
          }
-         break;
-         case TYPE_WM_NORMAL_HINTS:
-            break;
-         case TYPE_NET_WM_STATE:
-            handle_state(win, xcb_get_property_value(reply), reply->value_len, 
NET_WM_STATE_ADD);
-            break;
-         case TYPE_MOTIF_WM_HINTS:
-            // Motif hints
-            break;
+         wlc_dlog(WLC_DBG_XWM, "WM_PROTOCOLS: %u", view->type);
+      } else if (props[i] == x11.atoms[WM_NORMAL_HINTS]) {
+         wlc_dlog(WLC_DBG_XWM, "WM_NORMAL_HINTS");
+      } else if (props[i] == x11.atoms[NET_WM_STATE]) {
+         handle_state(win, xcb_get_property_value(reply), reply->value_len, 
NET_WM_STATE_ADD);
+         wlc_dlog(WLC_DBG_XWM, "NET_WM_STATE");
+      } else if (props[i] == x11.atoms[MOTIF_WM_HINTS]) {
+         // Motif hints
+         wlc_dlog(WLC_DBG_XWM, "MOTIF_WM_HINTS");
       }
 
       free(reply);
    }
 
    free(cookies);
+}
 
-#undef TYPE_WM_PROTOCOLS
-#undef TYPE_MOTIF_WM_HINTS
-#undef TYPE_NET_WM_STATE
-#undef TYPE_WM_NORMAL_HINTS
+static void
+get_properties(struct wlc_xwm *xwm, struct wlc_x11_window *win)
+{
+   const xcb_atom_t props[] = {
+      XCB_ATOM_WM_CLASS,
+      XCB_ATOM_WM_NAME,
+      XCB_ATOM_WM_TRANSIENT_FOR,
+      x11.atoms[WM_PROTOCOLS],
+      x11.atoms[WM_NORMAL_HINTS],
+      x11.atoms[NET_WM_STATE],
+      x11.atoms[NET_WM_WINDOW_TYPE],
+      x11.atoms[NET_WM_NAME],
+      x11.atoms[NET_WM_PID],
+      x11.atoms[MOTIF_WM_HINTS]
+   };
+
+   read_properties(xwm, win, props, LENGTH(props));
 }
 
 static void
@@ -372,7 +359,7 @@
 
    view->x11.paired = true;
    wlc_view_set_type_ptr(view, WLC_BIT_OVERRIDE_REDIRECT, 
view->x11.override_redirect);
-   read_properties(xwm, &view->x11);
+   get_properties(xwm, &view->x11);
 
    if (!wlc_geometry_equals(&geometry, &wlc_geometry_zero))
       wlc_view_set_geometry_ptr(view, 0, &geometry);
@@ -485,7 +472,7 @@
 {
    assert(win);
 
-   if (!x11.connection || !win->id)
+   if (!x11.connection || !win->id || win->override_redirect)
       return false;
 
    if (active) {
@@ -612,7 +599,7 @@
                wlc_dlog(WLC_DBG_XWM, "XCB_PROPERTY_NOTIFY (%u)", ev->window);
                struct wlc_x11_window *win;
                if ((win = paired_for_id(xwm, ev->window)) || (win = 
unpaired_for_id(xwm, ev->window)))
-                  read_properties(xwm, win);
+                  read_properties(xwm, win, &ev->atom, 1);
             }
             break;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlc-0.0.3/src/xwayland/xwm.h 
new/wlc-0.0.5/src/xwayland/xwm.h
--- old/wlc-0.0.3/src/xwayland/xwm.h    2016-05-22 21:15:27.000000000 +0200
+++ new/wlc-0.0.5/src/xwayland/xwm.h    2016-08-02 19:57:11.000000000 +0200
@@ -14,6 +14,7 @@
    uint32_t id; // xcb_window_t
    uint32_t surface_id;
    bool override_redirect;
+   bool has_utf8_title;
    bool has_delete_window;
    bool has_alpha;
    bool hidden; // HACK: used by output.c to hide invisible windows



Reply via email to