first commit
This commit is contained in:
commit
9ea6375874
5 changed files with 238 additions and 0 deletions
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ilia Bozhinov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
2
README.md
Normal file
2
README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# wayfire-plugins
|
||||
A repository for Wayfire plugins which I use to tweak my own desktop
|
34
meson.build
Normal file
34
meson.build
Normal file
|
@ -0,0 +1,34 @@
|
|||
project(
|
||||
'wf-roundedcorners',
|
||||
'c',
|
||||
'cpp',
|
||||
version: '0.1',
|
||||
license: 'MIT',
|
||||
meson_version: '>=0.51.0',
|
||||
default_options: [
|
||||
'cpp_std=c++17',
|
||||
'c_std=c11',
|
||||
'warning_level=2',
|
||||
'werror=false',
|
||||
],
|
||||
)
|
||||
|
||||
wayfire = dependency('wayfire')
|
||||
wlroots = dependency('wlroots')
|
||||
wfconfig = dependency('wf-config')
|
||||
|
||||
add_project_arguments(['-DWLR_USE_UNSTABLE'], language: ['cpp', 'c'])
|
||||
add_project_arguments(['-DWAYFIRE_PLUGIN'], language: ['cpp', 'c'])
|
||||
add_project_link_arguments(['-rdynamic'], language:'cpp')
|
||||
|
||||
subdir('src')
|
||||
subdir('metadata')
|
||||
|
||||
summary = [
|
||||
'',
|
||||
'----------------',
|
||||
'wf-roundcorner @0@'.format(meson.project_version()),
|
||||
'----------------',
|
||||
''
|
||||
]
|
||||
message('\n'.join(summary))
|
3
src/meson.build
Normal file
3
src/meson.build
Normal file
|
@ -0,0 +1,3 @@
|
|||
rc = shared_module('rounded-corners', 'rounded-corners.cpp',
|
||||
dependencies: [wayfire, wlroots],
|
||||
install: true, install_dir: wayfire.get_variable(pkgconfig: 'plugindir'))
|
178
src/rounded-corners.cpp
Normal file
178
src/rounded-corners.cpp
Normal file
|
@ -0,0 +1,178 @@
|
|||
#include <wayfire/view-transform.hpp>
|
||||
#include <wayfire/opengl.hpp>
|
||||
#include <wayfire/plugin.hpp>
|
||||
#include <wayfire/signal-definitions.hpp>
|
||||
#include <wayfire/util/log.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
const std::string vertex_source = R"(
|
||||
#version 100
|
||||
attribute mediump vec2 position;
|
||||
varying mediump vec2 fposition;
|
||||
|
||||
uniform mat4 matrix;
|
||||
|
||||
void main() {
|
||||
gl_Position = matrix * vec4(position, 0.0, 1.0);
|
||||
fposition = position;
|
||||
})";
|
||||
|
||||
const std::string frag_source = R"(
|
||||
#version 100
|
||||
@builtin_ext@
|
||||
|
||||
varying mediump vec2 fposition;
|
||||
@builtin@
|
||||
|
||||
// Top left corner
|
||||
uniform mediump vec2 top_left;
|
||||
|
||||
// Top left corner with shadows included
|
||||
uniform mediump vec2 full_top_left;
|
||||
|
||||
// Bottom right corner
|
||||
uniform mediump vec2 bottom_right;
|
||||
|
||||
// Bottom right corner with shadows included
|
||||
uniform mediump vec2 full_bottom_right;
|
||||
|
||||
// Rounding radius
|
||||
const mediump float radius = 20.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
mediump vec2 corner_dist = min(fposition - top_left, bottom_right - fposition);
|
||||
if (max(corner_dist.x, corner_dist.y) < radius)
|
||||
{
|
||||
if (distance(corner_dist, vec2(radius, radius)) > radius)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
highp vec2 uv = (fposition - full_top_left) / (full_bottom_right - full_top_left);
|
||||
uv.y = 1.0 - uv.y;
|
||||
gl_FragColor = get_pixel(uv);
|
||||
})";
|
||||
}
|
||||
|
||||
class rounded_corners_transformer_t : public wf::view_transformer_t
|
||||
{
|
||||
public:
|
||||
uint32_t get_z_order() override
|
||||
{
|
||||
return wf::TRANSFORMER_2D - 1;
|
||||
}
|
||||
|
||||
wf::region_t transform_opaque_region(
|
||||
wf::geometry_t box, wf::region_t region) override
|
||||
{
|
||||
(void)box;
|
||||
(void)region;
|
||||
return {};
|
||||
}
|
||||
|
||||
wf::pointf_t transform_point(
|
||||
wf::geometry_t view, wf::pointf_t point) override
|
||||
{
|
||||
(void)view;
|
||||
return point;
|
||||
}
|
||||
|
||||
wf::pointf_t untransform_point(
|
||||
wf::geometry_t view, wf::pointf_t point) override
|
||||
{
|
||||
(void)view;
|
||||
return point;
|
||||
}
|
||||
|
||||
wf::geometry_t get_bounding_box(wf::geometry_t bbox, wlr_box region) override
|
||||
{
|
||||
(void)bbox;
|
||||
return wf::geometry_intersection(this->view->get_wm_geometry(), region);
|
||||
}
|
||||
|
||||
std::vector<GLfloat> vertex_data;
|
||||
void upload_data(wlr_box src_box)
|
||||
{
|
||||
auto geometry = view->get_wm_geometry();
|
||||
float x = geometry.x, y = geometry.y,
|
||||
w = geometry.width, h = geometry.height;
|
||||
|
||||
vertex_data = {
|
||||
x, y + h,
|
||||
x + w, y + h,
|
||||
x + w, y,
|
||||
x, y,
|
||||
};
|
||||
program.attrib_pointer("position", 2, 0, vertex_data.data(), GL_FLOAT);
|
||||
|
||||
program.uniform2f("top_left", x, y);
|
||||
program.uniform2f("bottom_right", x + w, y + h);
|
||||
program.uniform2f("full_top_left", src_box.x, src_box.y);
|
||||
program.uniform2f("full_bottom_right",
|
||||
src_box.x + src_box.width, src_box.y + src_box.height);
|
||||
}
|
||||
|
||||
void render_with_damage(wf::texture_t src_tex, wlr_box src_box,
|
||||
const wf::region_t& damage, const wf::framebuffer_t& target_fb) override
|
||||
{
|
||||
OpenGL::render_begin(target_fb);
|
||||
|
||||
program.use(src_tex.type);
|
||||
program.set_active_texture(src_tex);
|
||||
upload_data(src_box);
|
||||
program.uniformMatrix4f("matrix", target_fb.get_orthographic_projection());
|
||||
|
||||
GL_CALL(glEnable(GL_BLEND));
|
||||
GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
|
||||
for (const auto& box : damage)
|
||||
{
|
||||
target_fb.logic_scissor(wlr_box_from_pixman_box(box));
|
||||
GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4));
|
||||
}
|
||||
|
||||
GL_CALL(glDisable(GL_BLEND));
|
||||
program.deactivate();
|
||||
OpenGL::render_end();
|
||||
}
|
||||
|
||||
rounded_corners_transformer_t(wayfire_view view)
|
||||
{
|
||||
this->view = view;
|
||||
|
||||
OpenGL::render_begin();
|
||||
program.compile(vertex_source, frag_source);
|
||||
OpenGL::render_end();
|
||||
}
|
||||
|
||||
virtual ~rounded_corners_transformer_t()
|
||||
{}
|
||||
|
||||
private:
|
||||
wayfire_view view;
|
||||
OpenGL::program_t program;
|
||||
};
|
||||
|
||||
class wayfire_rounded_corners_t : public wf::plugin_interface_t
|
||||
{
|
||||
public:
|
||||
void init() override
|
||||
{
|
||||
output->connect_signal("view-mapped", &on_map);
|
||||
}
|
||||
|
||||
wf::signal_connection_t on_map = [=] (wf::signal_data_t *data)
|
||||
{
|
||||
auto view = wf::get_signaled_view(data);
|
||||
// Ignore panels, backgrounds, etc.
|
||||
if (view->role == wf::VIEW_ROLE_TOPLEVEL)
|
||||
{
|
||||
view->add_transformer(
|
||||
std::make_unique<rounded_corners_transformer_t>(view));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
DECLARE_WAYFIRE_PLUGIN(wayfire_rounded_corners_t);
|
Loading…
Reference in a new issue