Repository: glium/glium (language: rust)

Issue:
Re-export winit
There are a lot of public exposed APIs that accept and return winit types (ie):

https://github.com/glium/glium/blob/1676f0de6dddfa294f834613372f5096a429acd8/src/backend/glutin/mod.rs#L333

Also, most of the tutorials make heavy use of the winit APIs.

Currently this requires users to figure out which version of winit is currently being used, and make sure their winit dependency stays in sync with the glium dependency, otherwise it will be a breaking change if your API expects a 0.29 EventLoop when the user is still using a 0.28 EventLoop.

It seems like you are aware of this, and are bumping semver minor to signify pre-1.0.0 breaking changes whenever you bump the winit dependency to a breaking change.

Since that is already a requirement on your library, you might as well re-export winit explicitly and change the tutorials to recommend using the re-export.


Discussion / hints:
Good point. Before, glutin did this for us, which we already export from the `backend::glutin` module. From that module, we could also export the winit dependency.
Just ran into this issue myself. Not the hardest thing to diagnose, but still a little bit annoying. An API compatible re-export of the correct version of winit would be nice in the glium crate. :)

Cheers
PRs welcome!

Fix patch:
diff --git a/book/tuto-01-getting-started.md b/book/tuto-01-getting-started.md
index d01de87748..41d3eba362 100644
--- a/book/tuto-01-getting-started.md
+++ b/book/tuto-01-getting-started.md
@@ -38,9 +38,11 @@ Initializing a simple OpenGL window with the default winit/glutin backend can be
 
 This will open a new window, register it with the given event_loop and create a (glutin) OpenGL context and glium Display while finally returning both the window and display to you.
 
+The following examples require the `simple_window_builder` feature, and provide a re-export of winit to prevent version mismatches.
+
 ```rust
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new().build().expect("event loop building");
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new().build().expect("event loop building");
     let (_window, display) = glium::backend::glutin::SimpleWindowBuilder::new().build(&event_loop);
 }
 ```
@@ -50,8 +52,8 @@ If you try to run this example with `cargo run` you'll encounter a problem: as s
 ```rust
 let _ = event_loop.run(move |event, window_target| {
     match event {
-        winit::event::Event::WindowEvent { event, .. } => match event {
-	    winit::event::WindowEvent::CloseRequested => window_target.exit(),
+        glium::winit::event::Event::WindowEvent { event, .. } => match event {
+	    glium::winit::event::WindowEvent::CloseRequested => window_target.exit(),
 	    _ => (),
         },
         _ => (),
@@ -100,7 +102,7 @@ Here is our full program:
 use glium::Surface;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new().build().expect("event loop building");
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new().build().expect("event loop building");
     let (_window, display) = glium::backend::glutin::SimpleWindowBuilder::new().build(&event_loop);
 
     let mut frame = display.draw();
@@ -109,8 +111,8 @@ fn main() {
 
     let _ = event_loop.run(move |event, window_target| {
         match event {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-	        winit::event::WindowEvent::CloseRequested => window_target.exit(),
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+	        glium::winit::event::WindowEvent::CloseRequested => window_target.exit(),
 	        _ => (),
             },
             _ => (),
diff --git a/book/tuto-03-animated-triangle.md b/book/tuto-03-animated-triangle.md
index c54b5494f2..c685fbe05b 100644
--- a/book/tuto-03-animated-triangle.md
+++ b/book/tuto-03-animated-triangle.md
@@ -7,9 +7,9 @@ So far we have only ever rendered a single frame and then waited for the program
 ```rust
 let _ = event_loop.run(move |event, window_target| {
     match event {
-        winit::event::Event::WindowEvent { event, .. } => match event {
-            winit::event::WindowEvent::CloseRequested => window_target.exit(),
-            winit::event::WindowEvent::RedrawRequested => {
+        glium::winit::event::Event::WindowEvent { event, .. } => match event {
+            glium::winit::event::WindowEvent::CloseRequested => window_target.exit(),
+            glium::winit::event::WindowEvent::RedrawRequested => {
                 // Move the draw code here!
             },
             _ => (),
@@ -24,14 +24,14 @@ What exactly triggers this event is platform specific, but in order to draw our
 ```rust
 let _ = event_loop.run(move |event, window_target| {
     match event {
-        winit::event::Event::WindowEvent { event, .. } => match event {
-            winit::event::WindowEvent::CloseRequested => window_target.exit(),
-            winit::event::WindowEvent::RedrawRequested => {
+        glium::winit::event::Event::WindowEvent { event, .. } => match event {
+            glium::winit::event::WindowEvent::CloseRequested => window_target.exit(),
+            glium::winit::event::WindowEvent::RedrawRequested => {
                 // Move the draw code here!
             },
             _ => (),
         },
-        winit::event::Event::AboutToWait => {
+        glium::winit::event::Event::AboutToWait => {
             window.request_redraw();
         },
         _ => (),
@@ -47,17 +47,17 @@ While we are working on our event_loop there is one more event that we should ha
 let mut t: f32 = 0.0;
 let _ = event_loop.run(move |event, window_target| {
     match event {
-        winit::event::Event::WindowEvent { event, .. } => match event {
-            winit::event::WindowEvent::CloseRequested => window_target.exit(),
-            winit::event::WindowEvent::Resized(window_size) => {
+        glium::winit::event::Event::WindowEvent { event, .. } => match event {
+            glium::winit::event::WindowEvent::CloseRequested => window_target.exit(),
+            glium::winit::event::WindowEvent::Resized(window_size) => {
                 display.resize(window_size.into());
             },
-            winit::event::WindowEvent::RedrawRequested => {
+            glium::winit::event::WindowEvent::RedrawRequested => {
                 // Move the draw code here!
             },
             _ => (),
         },
-        winit::event::Event::AboutToWait => {
+        glium::winit::event::Event::AboutToWait => {
             window.request_redraw();
         },
         _ => (),
@@ -75,12 +75,12 @@ Our first approach will be to create a variable named `t` which represents the s
 let mut t: f32 = 0.0;
 let _ = event_loop.run(move |event, window_target| {
     match event {
-        winit::event::Event::WindowEvent { event, .. } => match event {
-            winit::event::WindowEvent::CloseRequested => window_target.exit(),
-            winit::event::WindowEvent::Resized(window_size) => {
+        glium::winit::event::Event::WindowEvent { event, .. } => match event {
+            glium::winit::event::WindowEvent::CloseRequested => window_target.exit(),
+            glium::winit::event::WindowEvent::Resized(window_size) => {
                 display.resize(window_size.into());
             },
-            winit::event::WindowEvent::RedrawRequested => {
+            glium::winit::event::WindowEvent::RedrawRequested => {
                 // We update `t`
                 t += 0.02;
                 // We use the sine of t as an offset, this way we get a nice smooth animation
@@ -101,7 +101,7 @@ let _ = event_loop.run(move |event, window_target| {
             },
             _ => (),
         },
-        winit::event::Event::AboutToWait => {
+        glium::winit::event::Event::AboutToWait => {
             window.request_redraw();
         },
         _ => (),
@@ -127,12 +127,12 @@ Let's remove the two `let`'s that redefine our shape and vertex_buffer from our
 let mut t: f32 = 0.0;
 let _ = event_loop.run(move |event, window_target| {
     match event {
-        winit::event::Event::WindowEvent { event, .. } => match event {
-            winit::event::WindowEvent::CloseRequested => window_target.exit(),
-            winit::event::WindowEvent::Resized(window_size) => {
+        glium::winit::event::Event::WindowEvent { event, .. } => match event {
+            glium::winit::event::WindowEvent::CloseRequested => window_target.exit(),
+            glium::winit::event::WindowEvent::Resized(window_size) => {
                 display.resize(window_size.into());
             },
-	    winit::event::WindowEvent::RedrawRequested => {
+	    glium::winit::event::WindowEvent::RedrawRequested => {
 	        // We update `t`
 	        t += 0.02;
                 // We use the sine of t as an offset, this way we get a nice smooth animation
@@ -146,7 +146,7 @@ let _ = event_loop.run(move |event, window_target| {
 	    },
             _ => (),
         },
-        winit::event::Event::AboutToWait => {
+        glium::winit::event::Event::AboutToWait => {
             window.request_redraw();
         },
         _ => (),
diff --git a/examples/displacement_mapping.rs b/examples/displacement_mapping.rs
index 94affa7ec4..73ba9299bf 100644
--- a/examples/displacement_mapping.rs
+++ b/examples/displacement_mapping.rs
@@ -260,7 +260,7 @@ impl ApplicationContext for Application {
         frame.finish().unwrap();
     }
 
-    fn handle_window_event(&mut self, event: &winit::event::WindowEvent, _window: &winit::window::Window) {
+    fn handle_window_event(&mut self, event: &glium::winit::event::WindowEvent, _window: &glium::winit::window::Window) {
         self.camera.process_input(&event);
     }
 
diff --git a/examples/fullscreen.rs b/examples/fullscreen.rs
index 1b76dcd8a2..39a297010e 100644
--- a/examples/fullscreen.rs
+++ b/examples/fullscreen.rs
@@ -8,7 +8,7 @@ use glium::index::PrimitiveType;
 use glium::{Display, Frame, Surface};
 use glutin::surface::WindowSurface;
 use support::{ApplicationContext, State};
-use winit::{window::Fullscreen, keyboard::{PhysicalKey, KeyCode}};
+use glium::winit::{window::Fullscreen, keyboard::{PhysicalKey, KeyCode}};
 
 mod support;
 
@@ -29,7 +29,7 @@ struct Application {
 }
 
 impl Application {
-    fn toggle_fullscreen(&mut self, window: &winit::window::Window) {
+    fn toggle_fullscreen(&mut self, window: &glium::winit::window::Window) {
         if self.fullscreen {
             window.set_fullscreen(None);
             self.fullscreen = false;
@@ -123,10 +123,10 @@ impl ApplicationContext for Application {
         frame.finish().unwrap();
     }
 
-    fn handle_window_event(&mut self, event: &winit::event::WindowEvent, window: &winit::window::Window) {
+    fn handle_window_event(&mut self, event: &glium::winit::event::WindowEvent, window: &glium::winit::window::Window) {
         match event {
-            winit::event::WindowEvent::KeyboardInput { event, .. } => match event.state {
-                winit::event::ElementState::Pressed => match event.physical_key {
+            glium::winit::event::WindowEvent::KeyboardInput { event, .. } => match event.state {
+                glium::winit::event::ElementState::Pressed => match event.physical_key {
                     PhysicalKey::Code(KeyCode::Enter) => {
                         self.toggle_fullscreen(window);
                     }
diff --git a/examples/fxaa.rs b/examples/fxaa.rs
index 7c6a414f62..0cb76a33dc 100644
--- a/examples/fxaa.rs
+++ b/examples/fxaa.rs
@@ -1,12 +1,12 @@
 #[macro_use]
 extern crate glium;
 
-use std::{cell::RefCell};
+use std::cell::RefCell;
 
 use glium::{Display, Surface, framebuffer::SimpleFrameBuffer};
 use glutin::surface::WindowSurface;
 use support::{ApplicationContext, State};
-use winit::keyboard::{PhysicalKey, KeyCode};
+use glium::winit::keyboard::{PhysicalKey, KeyCode};
 
 mod support;
 
@@ -275,12 +275,12 @@ impl ApplicationContext for Application {
         target.finish().unwrap();
     }
 
-    fn handle_window_event(&mut self, event: &winit::event::WindowEvent, _window: &winit::window::Window) {
+    fn handle_window_event(&mut self, event: &glium::winit::event::WindowEvent, _window: &glium::winit::window::Window) {
         self.camera.process_input(&event);
 
         match event {
-            winit::event::WindowEvent::KeyboardInput { event, .. } => match event.state {
-                winit::event::ElementState::Pressed => match event.physical_key {
+            glium::winit::event::WindowEvent::KeyboardInput { event, .. } => match event.state {
+                glium::winit::event::ElementState::Pressed => match event.physical_key {
                     PhysicalKey::Code(KeyCode::Space) => {
                         self.fxaa_enabled = !self.fxaa_enabled;
                         println!("FXAA is now {}", if self.fxaa_enabled { "enabled" } else { "disabled" });
diff --git a/examples/instancing.rs b/examples/instancing.rs
index 9912bb7910..2d5b63fd00 100644
--- a/examples/instancing.rs
+++ b/examples/instancing.rs
@@ -131,7 +131,7 @@ impl ApplicationContext for Application {
         frame.finish().unwrap();
     }
 
-    fn handle_window_event(&mut self, event: &winit::event::WindowEvent, _window: &winit::window::Window) {
+    fn handle_window_event(&mut self, event: &glium::winit::event::WindowEvent, _window: &glium::winit::window::Window) {
         self.camera.process_input(&event);
     }
 
diff --git a/examples/manual-creation.rs b/examples/manual-creation.rs
index 75c3146005..643ba0c2fe 100644
--- a/examples/manual-creation.rs
+++ b/examples/manual-creation.rs
@@ -17,8 +17,8 @@ There are three concepts in play:
 
 */
 
-use winit::event_loop::EventLoopBuilder;
-use winit::window::WindowBuilder;
+use glium::winit::event_loop::EventLoopBuilder;
+use glium::winit::window::WindowBuilder;
 use glium::Surface;
 use glutin::surface::WindowSurface;
 use glutin::config::ConfigTemplateBuilder;
@@ -158,8 +158,8 @@ fn main() {
     // the window is still available
     event_loop.run(|event, window_target| {
         match event {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => window_target.exit(),
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => window_target.exit(),
                 _ => (),
             },
             _ => (),
diff --git a/examples/multiple_windows.rs b/examples/multiple_windows.rs
index af1e51ecb0..ae45663cc4 100644
--- a/examples/multiple_windows.rs
+++ b/examples/multiple_windows.rs
@@ -6,7 +6,7 @@ use std::collections::HashMap;
 use glium::{Surface, Display};
 use glutin::surface::WindowSurface;
 use support::{ApplicationContext, State};
-use winit::{window::WindowId, event_loop::EventLoopBuilder};
+use glium::winit::{window::WindowId, event_loop::EventLoopBuilder};
 
 mod support;
 
@@ -46,20 +46,20 @@ fn main() {
         match event {
             // The Resumed/Suspended events are mostly for Android compatiblity since the context can get lost there at any point.
             // For convenience's sake the Resumed event is also delivered on other platforms on program startup.
-            winit::event::Event::Resumed => {
+            glium::winit::event::Event::Resumed => {
                 // On startup we create the main window and insert it into the HashMap just like subsequent sub windows.
                 let window:State<Application> = State::new(window_target, true);
                 windows.insert(window.window.id(), window);
             },
-            winit::event::Event::Suspended => {
+            glium::winit::event::Event::Suspended => {
                 windows.clear();
             },
-            winit::event::Event::WindowEvent { event, window_id, .. } => {
+            glium::winit::event::Event::WindowEvent { event, window_id, .. } => {
                 if let Some(state) = windows.get_mut(&window_id) {
                     match event {
-                        winit::event::WindowEvent::MouseInput {
-                            state: winit::event::ElementState::Released,
-                            button: winit::event::MouseButton::Left,
+                        glium::winit::event::WindowEvent::MouseInput {
+                            state: glium::winit::event::ElementState::Released,
+                            button: glium::winit::event::MouseButton::Left,
                             ..
                         } => {
                             // This is the main part, where we actually create the new window, enumerate it and
@@ -74,11 +74,11 @@ fn main() {
                                 windows.remove(&window_id);
                             }
                         },
-                        winit::event::WindowEvent::RedrawRequested => {
+                        glium::winit::event::WindowEvent::RedrawRequested => {
                             state.context.update();
                             state.context.draw_frame(&state.display);
                         }
-                        winit::event::WindowEvent::CloseRequested => {
+                        glium::winit::event::WindowEvent::CloseRequested => {
                             if state.context.id == 1 {
                                 window_target.exit();
                             } else {
@@ -87,7 +87,7 @@ fn main() {
                         },
                         // These two aren't necessary for this particular example, but forgetting especially the Resized
                         // event could lead to stretched images being rendered if you decide to render something more interesting based on this example.
-                        winit::event::WindowEvent::Resized(new_size) => {
+                        glium::winit::event::WindowEvent::Resized(new_size) => {
                             state.display.resize(new_size.into());
                         },
                         ev => {
diff --git a/examples/picking.rs b/examples/picking.rs
index 606242e125..d3264fdfc5 100644
--- a/examples/picking.rs
+++ b/examples/picking.rs
@@ -258,9 +258,9 @@ impl ApplicationContext for Application {
         }
     }
 
-    fn handle_window_event(&mut self, event: &winit::event::WindowEvent, _window: &winit::window::Window) {
+    fn handle_window_event(&mut self, event: &glium::winit::event::WindowEvent, _window: &glium::winit::window::Window) {
         match event {
-            winit::event::WindowEvent::CursorMoved { position, .. } => {
+            glium::winit::event::WindowEvent::CursorMoved { position, .. } => {
                 self.cursor_position = Some(position.cast::<i32>().into());
             }
             ev => self.camera.process_input(ev),
diff --git a/examples/screenshot-asynchronous.rs b/examples/screenshot-asynchronous.rs
index 64f6c86d9a..86b62bc77a 100644
--- a/examples/screenshot-asynchronous.rs
+++ b/examples/screenshot-asynchronous.rs
@@ -7,7 +7,7 @@ use glium::index::PrimitiveType;
 use glium::{Display, Surface};
 use glutin::surface::WindowSurface;
 use support::{ApplicationContext, State};
-use winit::keyboard::{PhysicalKey, KeyCode};
+use glium::winit::keyboard::{PhysicalKey, KeyCode};
 
 mod screenshot {
     use glium::Surface;
@@ -269,9 +269,9 @@ impl ApplicationContext for Application {
         }
     }
 
-    fn handle_window_event(&mut self, event: &winit::event::WindowEvent, _window: &winit::window::Window) {
-        if let winit::event::WindowEvent::KeyboardInput { event, ..} = event {
-            if let winit::event::ElementState::Pressed = event.state {
+    fn handle_window_event(&mut self, event: &glium::winit::event::WindowEvent, _window: &glium::winit::window::Window) {
+        if let glium::winit::event::WindowEvent::KeyboardInput { event, ..} = event {
+            if let glium::winit::event::ElementState::Pressed = event.state {
                 if let PhysicalKey::Code(KeyCode::KeyS) = event.physical_key {
                     self.take_screenshot = true;
                 }
@@ -282,4 +282,4 @@ impl ApplicationContext for Application {
 
 fn main() {
     State::<Application>::run_loop();
-}
\ No newline at end of file
+}
diff --git a/examples/shadow_mapping.rs b/examples/shadow_mapping.rs
index 09d61542ed..cc912a1e0f 100644
--- a/examples/shadow_mapping.rs
+++ b/examples/shadow_mapping.rs
@@ -2,7 +2,7 @@
 extern crate glium;
 
 use cgmath::SquareMatrix;
-use winit::keyboard::{PhysicalKey, KeyCode};
+use glium::winit::keyboard::{PhysicalKey, KeyCode};
 use std::time::Instant;
 use glium::{Surface, Display, VertexBuffer, IndexBuffer, Program, texture::DepthTexture2d};
 use glutin::surface::WindowSurface;
@@ -275,9 +275,9 @@ impl ApplicationContext for Application {
         }
     }
 
-    fn handle_window_event(&mut self, event: &winit::event::WindowEvent, _window: &winit::window::Window) {
+    fn handle_window_event(&mut self, event: &glium::winit::event::WindowEvent, _window: &glium::winit::window::Window) {
         match event {
-            winit::event::WindowEvent::KeyboardInput { event, .. } => if event.state == winit::event::ElementState::Pressed {
+            glium::winit::event::WindowEvent::KeyboardInput { event, .. } => if event.state == glium::winit::event::ElementState::Pressed {
                 if let PhysicalKey::Code(code) = event.physical_key {
                     match code {
                         KeyCode::KeyC => self.camera_rotating = !self.camera_rotating,
diff --git a/examples/spirv/main.rs b/examples/spirv/main.rs
index e570373d3a..2039894be6 100644
--- a/examples/spirv/main.rs
+++ b/examples/spirv/main.rs
@@ -16,10 +16,10 @@ use raw_window_handle::HasRawWindowHandle;
 
 fn main() {
     // We start by creating the main EventLoop
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
-    let window_builder = winit::window::WindowBuilder::new().with_title("Glium SPIR-V example");
+    let window_builder = glium::winit::window::WindowBuilder::new().with_title("Glium SPIR-V example");
     let config_template_builder = glutin::config::ConfigTemplateBuilder::new();
     let display_builder = glutin_winit::DisplayBuilder::new().with_window_builder(Some(window_builder));
 
diff --git a/examples/support/camera.rs b/examples/support/camera.rs
index 94ff610659..f429bec7be 100644
--- a/examples/support/camera.rs
+++ b/examples/support/camera.rs
@@ -148,12 +148,12 @@ impl CameraState {
         }
     }
 
-    pub fn process_input(&mut self, event: &winit::event::WindowEvent) {
-        use winit::keyboard::{PhysicalKey, KeyCode};
-        let winit::event::WindowEvent::KeyboardInput { event, .. } = event else {
+    pub fn process_input(&mut self, event: &glium::winit::event::WindowEvent) {
+        use glium::winit::keyboard::{PhysicalKey, KeyCode};
+        let glium::winit::event::WindowEvent::KeyboardInput { event, .. } = event else {
             return
         };
-        let pressed = event.state == winit::event::ElementState::Pressed;
+        let pressed = event.state == glium::winit::event::ElementState::Pressed;
         match &event.physical_key {
             PhysicalKey::Code(KeyCode::ArrowUp) => self.moving_up = pressed,
             PhysicalKey::Code(KeyCode::ArrowDown) => self.moving_down = pressed,
diff --git a/examples/support/mod.rs b/examples/support/mod.rs
index 1a3aed3de9..b1b3065ba7 100644
--- a/examples/support/mod.rs
+++ b/examples/support/mod.rs
@@ -88,22 +88,22 @@ pub trait ApplicationContext {
     fn draw_frame(&mut self, _display: &Display<WindowSurface>) { }
     fn new(display: &Display<WindowSurface>) -> Self;
     fn update(&mut self) { }
-    fn handle_window_event(&mut self, _event: &winit::event::WindowEvent, _window: &winit::window::Window) { }
+    fn handle_window_event(&mut self, _event: &glium::winit::event::WindowEvent, _window: &glium::winit::window::Window) { }
     const WINDOW_TITLE:&'static str;
 }
 
 pub struct State<T> {
     pub display: glium::Display<WindowSurface>,
-    pub window: winit::window::Window,
+    pub window: glium::winit::window::Window,
     pub context: T,
 }
 
 impl<T: ApplicationContext + 'static> State<T> {
     pub fn new<W>(
-        event_loop: &winit::event_loop::EventLoopWindowTarget<W>,
+        event_loop: &glium::winit::event_loop::EventLoopWindowTarget<W>,
         visible: bool,
     ) -> Self {
-        let window_builder = winit::window::WindowBuilder::new().with_title(T::WINDOW_TITLE).with_visible(visible);
+        let window_builder = glium::winit::window::WindowBuilder::new().with_title(T::WINDOW_TITLE).with_visible(visible);
         let config_template_builder = glutin::config::ConfigTemplateBuilder::new();
         let display_builder = glutin_winit::DisplayBuilder::new().with_window_builder(Some(window_builder));
 
@@ -150,7 +150,7 @@ impl<T: ApplicationContext + 'static> State<T> {
 
     pub fn from_display_window(
         display: glium::Display<WindowSurface>,
-        window: winit::window::Window,
+        window: glium::winit::window::Window,
     ) -> Self {
         let context = T::new(&display);
         Self {
@@ -162,7 +162,7 @@ impl<T: ApplicationContext + 'static> State<T> {
 
     /// Start the event_loop and keep rendering frames until the program is closed
     pub fn run_loop() {
-        let event_loop = winit::event_loop::EventLoopBuilder::new()
+        let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
             .build()
             .expect("event loop building");
         let mut state: Option<State<T>> = None;
@@ -171,24 +171,24 @@ impl<T: ApplicationContext + 'static> State<T> {
             match event {
                 // The Resumed/Suspended events are mostly for Android compatiblity since the context can get lost there at any point.
                 // For convenience's sake the Resumed event is also delivered on other platforms on program startup.
-                winit::event::Event::Resumed => {
+                glium::winit::event::Event::Resumed => {
                     state = Some(State::new(window_target, true));
                 },
-                winit::event::Event::Suspended => state = None,
+                glium::winit::event::Event::Suspended => state = None,
                 // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
                 // For applications that only change due to user input you could remove this handler.
-                winit::event::Event::AboutToWait => {
+                glium::winit::event::Event::AboutToWait => {
                     if let Some(state) = &state {
                         state.window.request_redraw();
                     }
                 }
-                winit::event::Event::WindowEvent { event, .. } => match event {
-                    winit::event::WindowEvent::Resized(new_size) => {
+                glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                    glium::winit::event::WindowEvent::Resized(new_size) => {
                         if let Some(state) = &state {
                             state.display.resize(new_size.into());
                         }
                     },
-                    winit::event::WindowEvent::RedrawRequested => {
+                    glium::winit::event::WindowEvent::RedrawRequested => {
                         if let Some(state) = &mut state {
                             state.context.update();
                             state.context.draw_frame(&state.display);
@@ -196,10 +196,10 @@ impl<T: ApplicationContext + 'static> State<T> {
                     },
                     // Exit the event loop when requested (by closing the window for example) or when
                     // pressing the Esc key.
-                    winit::event::WindowEvent::CloseRequested
-                    | winit::event::WindowEvent::KeyboardInput { event: winit::event::KeyEvent {
-                        state: winit::event::ElementState::Pressed,
-                        logical_key: winit::keyboard::Key::Named(winit::keyboard::NamedKey::Escape),
+                    glium::winit::event::WindowEvent::CloseRequested
+                    | glium::winit::event::WindowEvent::KeyboardInput { event: glium::winit::event::KeyEvent {
+                        state: glium::winit::event::ElementState::Pressed,
+                        logical_key: glium::winit::keyboard::Key::Named(glium::winit::keyboard::NamedKey::Escape),
                         ..
                     }, ..} => {
                         window_target.exit()
@@ -219,7 +219,7 @@ impl<T: ApplicationContext + 'static> State<T> {
 
     /// Create a context and draw a single frame
     pub fn run_once(visible: bool) {
-        let event_loop = winit::event_loop::EventLoopBuilder::new()
+        let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
             .build()
             .expect("event loop building");
         let mut state:State<T> = State::new(&event_loop, visible);
diff --git a/examples/teapot.rs b/examples/teapot.rs
index e5237ab452..83768d5f4c 100644
--- a/examples/teapot.rs
+++ b/examples/teapot.rs
@@ -164,7 +164,7 @@ impl ApplicationContext for Application {
         frame.finish().unwrap();
     }
 
-    fn handle_window_event(&mut self, event: &winit::event::WindowEvent, _window: &winit::window::Window) {
+    fn handle_window_event(&mut self, event: &glium::winit::event::WindowEvent, _window: &glium::winit::window::Window) {
         self.camera.process_input(&event);
     }
 
diff --git a/examples/tessellation.rs b/examples/tessellation.rs
index e3429943db..dc16d3a45a 100644
--- a/examples/tessellation.rs
+++ b/examples/tessellation.rs
@@ -189,11 +189,11 @@ impl ApplicationContext for Application {
         frame.finish().unwrap();
     }
 
-    fn handle_window_event(&mut self, event: &winit::event::WindowEvent, _window: &winit::window::Window) {
-        use winit::keyboard::{PhysicalKey, KeyCode};
+    fn handle_window_event(&mut self, event: &glium::winit::event::WindowEvent, _window: &glium::winit::window::Window) {
+        use glium::winit::keyboard::{PhysicalKey, KeyCode};
         match event {
-            winit::event::WindowEvent::KeyboardInput { event, .. } => match event.state {
-                winit::event::ElementState::Pressed => match event.physical_key {
+            glium::winit::event::WindowEvent::KeyboardInput { event, .. } => match event.state {
+                glium::winit::event::ElementState::Pressed => match event.physical_key {
                     PhysicalKey::Code(KeyCode::ArrowUp) => {
                         self.tess_level += 1;
                         println!("New tessellation level: {}", self.tess_level);
diff --git a/examples/tutorial-01.rs b/examples/tutorial-01.rs
index 2a673a8b08..2a8223b2a7 100644
--- a/examples/tutorial-01.rs
+++ b/examples/tutorial-01.rs
@@ -3,7 +3,7 @@ use glium::Surface;
 fn main() {
     // We start by creating the EventLoop, this can only be done once per process.
     // This also needs to happen on the main thread to make the program portable.
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (_window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -20,9 +20,9 @@ fn main() {
     // Now we wait until the program is closed
     event_loop.run(move |event, window_target| {
         match event {
-            winit::event::Event::WindowEvent { event, .. } => match event {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
                 // This event is sent by the OS when you close the Window, or request the program to quit via the taskbar.
-                winit::event::WindowEvent::CloseRequested => window_target.exit(),
+                glium::winit::event::WindowEvent::CloseRequested => window_target.exit(),
                 _ => (),
             },
             _ => (),
diff --git a/examples/tutorial-02.rs b/examples/tutorial-02.rs
index 58af8bc0c1..01f1809434 100644
--- a/examples/tutorial-02.rs
+++ b/examples/tutorial-02.rs
@@ -5,7 +5,7 @@ use glium::Surface;
 fn main() {
     // We start by creating the EventLoop, this can only be done once per process.
     // This also needs to happen on the main thread to make the program portable.
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (_window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -55,8 +55,8 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 _ => (),
diff --git a/examples/tutorial-03.rs b/examples/tutorial-03.rs
index 04f2094657..d76fca3d86 100644
--- a/examples/tutorial-03.rs
+++ b/examples/tutorial-03.rs
@@ -3,7 +3,7 @@ extern crate glium;
 use glium::Surface;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -51,12 +51,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     // first we update `t`
                     t += 0.02;
                     let x_off = t.sin() * 0.5;
@@ -70,14 +70,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a RedrawEventsCleared event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/examples/tutorial-04.rs b/examples/tutorial-04.rs
index b8c41dc861..ea70b31326 100644
--- a/examples/tutorial-04.rs
+++ b/examples/tutorial-04.rs
@@ -3,7 +3,7 @@ extern crate glium;
 use glium::Surface;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -50,12 +50,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     // we update `t`
                     t += 0.02;
                     let x = t.sin() * 0.5;
@@ -78,14 +78,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/examples/tutorial-05.rs b/examples/tutorial-05.rs
index 6b9efdad64..8f990c890b 100644
--- a/examples/tutorial-05.rs
+++ b/examples/tutorial-05.rs
@@ -3,7 +3,7 @@ extern crate glium;
 use glium::Surface;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -56,12 +56,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     // we update `t`
                     t += 0.02;
                     let x = t.sin() * 0.5;
@@ -84,14 +84,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/examples/tutorial-06.rs b/examples/tutorial-06.rs
index 0f6dbbc955..010de83780 100644
--- a/examples/tutorial-06.rs
+++ b/examples/tutorial-06.rs
@@ -3,7 +3,7 @@ extern crate glium;
 use glium::Surface;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -67,12 +67,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     // we update `t`
                     t += 0.02;
                     let x = t.sin() * 0.5;
@@ -96,14 +96,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/examples/tutorial-07.rs b/examples/tutorial-07.rs
index 26cad4fb6c..016b4d7634 100644
--- a/examples/tutorial-07.rs
+++ b/examples/tutorial-07.rs
@@ -6,7 +6,7 @@ use glium::Surface;
 mod teapot;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -46,12 +46,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     let mut target = display.draw();
                     target.clear_color(0.0, 0.0, 1.0, 1.0);
 
@@ -68,14 +68,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/examples/tutorial-08.rs b/examples/tutorial-08.rs
index fb5e36ea66..1d4e81776a 100644
--- a/examples/tutorial-08.rs
+++ b/examples/tutorial-08.rs
@@ -6,7 +6,7 @@ use glium::Surface;
 mod teapot;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -54,12 +54,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     let mut target = display.draw();
                     target.clear_color(0.0, 0.0, 1.0, 1.0);
 
@@ -79,14 +79,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/examples/tutorial-09.rs b/examples/tutorial-09.rs
index 49dc0e24c9..227a42c02c 100644
--- a/examples/tutorial-09.rs
+++ b/examples/tutorial-09.rs
@@ -6,7 +6,7 @@ use glium::Surface;
 mod teapot;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -54,12 +54,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     let mut target = display.draw();
                     target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
 
@@ -87,14 +87,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/examples/tutorial-10.rs b/examples/tutorial-10.rs
index 711ce507ec..3a65979599 100644
--- a/examples/tutorial-10.rs
+++ b/examples/tutorial-10.rs
@@ -6,7 +6,7 @@ use glium::Surface;
 mod teapot;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -55,12 +55,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     let mut target = display.draw();
                     target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
 
@@ -107,14 +107,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/examples/tutorial-12.rs b/examples/tutorial-12.rs
index 3f5aa403c1..d4616521e2 100644
--- a/examples/tutorial-12.rs
+++ b/examples/tutorial-12.rs
@@ -9,7 +9,7 @@ mod support;
 use support::view_matrix;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -60,12 +60,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     let mut target = display.draw();
                     target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
 
@@ -115,14 +115,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/examples/tutorial-13.rs b/examples/tutorial-13.rs
index 4027c911e5..4ece9b977f 100644
--- a/examples/tutorial-13.rs
+++ b/examples/tutorial-13.rs
@@ -9,7 +9,7 @@ mod support;
 use support::view_matrix;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -72,12 +72,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     let mut target = display.draw();
                     target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
 
@@ -127,14 +127,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/examples/tutorial-14.rs b/examples/tutorial-14.rs
index 05dcb09e6b..02d8ea4d4d 100644
--- a/examples/tutorial-14.rs
+++ b/examples/tutorial-14.rs
@@ -6,7 +6,7 @@ mod support;
 use support::view_matrix;
 
 fn main() {
-    let event_loop = winit::event_loop::EventLoopBuilder::new()
+    let event_loop = glium::winit::event_loop::EventLoopBuilder::new()
         .build()
         .expect("event loop building");
     let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
@@ -119,12 +119,12 @@ fn main() {
 
     event_loop.run(move |ev, window_target| {
         match ev {
-            winit::event::Event::WindowEvent { event, .. } => match event {
-                winit::event::WindowEvent::CloseRequested => {
+            glium::winit::event::Event::WindowEvent { event, .. } => match event {
+                glium::winit::event::WindowEvent::CloseRequested => {
                     window_target.exit();
                 },
                 // We now need to render everyting in response to a RedrawRequested event due to the animation
-                winit::event::WindowEvent::RedrawRequested => {
+                glium::winit::event::WindowEvent::RedrawRequested => {
                     let mut target = display.draw();
                     target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
 
@@ -177,14 +177,14 @@ fn main() {
                 },
                 // Because glium doesn't know about windows we need to resize the display
                 // when the window's size has changed.
-                winit::event::WindowEvent::Resized(window_size) => {
+                glium::winit::event::WindowEvent::Resized(window_size) => {
                     display.resize(window_size.into());
                 },
                 _ => (),
             },
             // By requesting a redraw in response to a AboutToWait event we get continuous rendering.
             // For applications that only change due to user input you could remove this handler.
-            winit::event::Event::AboutToWait => {
+            glium::winit::event::Event::AboutToWait => {
                 window.request_redraw();
             },
             _ => (),
diff --git a/src/backend/mod.rs b/src/backend/mod.rs
index 2033ed5a5d..3aee8aa0ab 100644
--- a/src/backend/mod.rs
+++ b/src/backend/mod.rs
@@ -29,6 +29,9 @@ pub use crate::context::ReleaseBehavior;
 #[cfg(feature = "glutin")]
 pub mod glutin;
 
+#[cfg(feature = "simple_window_builder")]
+pub use winit;
+
 /// Trait for types that can be used as a backend for a glium context.
 ///
 /// This trait is unsafe, as you can get undefined behaviors or crashes if you don't implement
diff --git a/src/lib.rs b/src/lib.rs
index af8e9b9d96..439534dc95 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,7 +12,9 @@ The initialisation of a simple glium display occurs in two steps.
 
 ```no_run
 extern crate glium;
-extern crate winit;
+// Use the re-exported winit dependency to avoid version mismatches.
+// Requires the `simple_window_builder` feature.
+use glium::winit;
 
 fn main() {
     // 1. The **winit::EventLoop** for handling events.
@@ -108,6 +110,8 @@ result to the user.
 
 #[cfg(feature = "glutin")]
 pub use crate::backend::glutin::glutin;
+#[cfg(feature = "simple_window_builder")]
+pub use crate::backend::winit;
 pub use crate::context::{Capabilities, ExtensionsList, Profile, UuidError};
 pub use crate::draw_parameters::{Blend, BlendingFunction, LinearBlendingFactor, BackfaceCullingMode};
 pub use crate::draw_parameters::{Depth, DepthTest, PolygonMode, DrawParameters, StencilTest, StencilOperation};


Test patch:
diff --git a/tests/support/mod.rs b/tests/support/mod.rs
index a2a0b997ef..6267b4fe2e 100644
--- a/tests/support/mod.rs
+++ b/tests/support/mod.rs
@@ -16,9 +16,9 @@ use glutin::prelude::*;
 use glutin::surface::{SurfaceAttributesBuilder, WindowSurface};
 use glutin_winit::DisplayBuilder;
 use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
-use winit::event::Event;
-use winit::event_loop::{EventLoopBuilder, EventLoopProxy};
-use winit::window::{Window, WindowBuilder, WindowId};
+use glium::winit::event::Event;
+use glium::winit::event_loop::{EventLoopBuilder, EventLoopProxy};
+use glium::winit::window::{Window, WindowBuilder, WindowId};
 
 use std::collections::HashMap;
 use std::env;
@@ -31,9 +31,9 @@ use std::thread;
 
 // There is a Wayland version of this extension trait but the X11 version also works on Wayland
 #[cfg(unix)]
-use winit::platform::x11::EventLoopBuilderExtX11;
+use glium::winit::platform::x11::EventLoopBuilderExtX11;
 #[cfg(windows)]
-use winit::platform::windows::EventLoopBuilderExtWindows;
+use glium::winit::platform::windows::EventLoopBuilderExtWindows;
 
 // Thread communication
 static mut EVENT_LOOP_PROXY: RwLock<Option<EventLoopProxy<()>>> = RwLock::new(None);
@@ -220,8 +220,8 @@ pub fn rebuild_display(_display: &glium::Display<WindowSurface>) {
     todo!();
     /*
     let version = parse_version();
-    let event_loop = winit::event_loop::EventLoop::new();
-    let wb = winit::window::WindowBuilder::new().with_visible(false);
+    let event_loop = glium::winit::event_loop::EventLoop::new();
+    let wb = glium::winit::window::WindowBuilder::new().with_visible(false);
     let cb = glutin::ContextBuilder::new()
         .with_gl_debug_flag(true)
         .with_gl(version);